# industry.h

Go to the documentation of this file.

    00001 /* $Id: industry.h 15428 2009-02-09 02:57:15Z rubidium $ */
    00002
    00005 #ifndef INDUSTRY_H
    00006 #define INDUSTRY_H
    00007
    00008 #include "oldpool.h"
    00009 #include "core/random_func.hpp"
    00010 #include "newgrf_storage.h"
    00011 #include "cargo_type.h"
    00012 #include "economy_type.h"
    00013 #include "map_type.h"
    00014 #include "slope_type.h"
    00015 #include "date_type.h"
    00016 #include "town_type.h"
    00017 #include "industry_type.h"
    00018 #include "landscape_type.h"
    00019
    00020 enum {
    00021   INVALID_INDUSTRY       = 0xFFFF,
    00022   NEW_INDUSTRYOFFSET     = 37,
    00023   NUM_INDUSTRYTYPES      = 64,
    00024   INDUSTRYTILE_NOANIM    = 0xFF,
    00025   NEW_INDUSTRYTILEOFFSET = 175,
    00026   INVALID_INDUSTRYTYPE   = NUM_INDUSTRYTYPES,
    00027   NUM_INDUSTRYTILES      = 512,
    00028   INVALID_INDUSTRYTILE   = NUM_INDUSTRYTILES,
    00029   INDUSTRY_COMPLETED     = 3,
    00030 };
    00031
    00032 enum {
    00033   CLEAN_RANDOMSOUNDS,
    00034   CLEAN_TILELSAYOUT,
    00035 };
    00036
    00037 enum IndustryLifeType {
    00038   INDUSTRYLIFE_BLACK_HOLE =      0,
    00039   INDUSTRYLIFE_EXTRACTIVE = 1 << 0,
    00040   INDUSTRYLIFE_ORGANIC    = 1 << 1,
    00041   INDUSTRYLIFE_PROCESSING = 1 << 2,
    00042 };
    00043
    00044 /* Procedures that can be run to check whether an industry may
    00045  * build at location the given to the procedure */
    00046 enum CheckProc {
    00047   CHECK_NOTHING,
    00048   CHECK_FOREST,
    00049   CHECK_REFINERY,
    00050   CHECK_FARM,
    00051   CHECK_PLANTATION,
    00052   CHECK_WATER,
    00053   CHECK_LUMBERMILL,
    00054   CHECK_BUBBLEGEN,
    00055   CHECK_OIL_RIG,
    00056   CHECK_END,
    00057 };
    00058
    00060 enum IndustryConstructionType {
    00061   ICT_UNKNOWN,
    00062   ICT_NORMAL_GAMEPLAY,
    00063   ICT_MAP_GENERATION,
    00064   ICT_SCENARIO_EDITOR
    00065 };
    00066
    00067 enum IndustryBehaviour {
    00068   INDUSTRYBEH_NONE                  =      0,
    00069   INDUSTRYBEH_PLANT_FIELDS          = 1 << 0,
    00070   INDUSTRYBEH_CUT_TREES             = 1 << 1,
    00071   INDUSTRYBEH_BUILT_ONWATER         = 1 << 2,
    00072   INDUSTRYBEH_TOWN1200_MORE         = 1 << 3,
    00073   INDUSTRYBEH_ONLY_INTOWN           = 1 << 4,
    00074   INDUSTRYBEH_ONLY_NEARTOWN         = 1 << 5,
    00075   INDUSTRYBEH_PLANT_ON_BUILT        = 1 << 6,
    00076   INDUSTRYBEH_DONT_INCR_PROD        = 1 << 7,
    00077   INDUSTRYBEH_BEFORE_1950           = 1 << 8,
    00078   INDUSTRYBEH_AFTER_1960            = 1 << 9,
    00079   INDUSTRYBEH_AI_AIRSHIP_ROUTES     = 1 << 10,
    00080   INDUSTRYBEH_AIRPLANE_ATTACKS      = 1 << 11,
    00081   INDUSTRYBEH_CHOPPER_ATTACKS       = 1 << 12,
    00082   INDUSTRYBEH_CAN_SUBSIDENCE        = 1 << 13,
    00083   /* The following flags are only used for newindustries and do no represent any normal behaviour */
    00084   INDUSTRYBEH_PROD_MULTI_HNDLING    = 1 << 14,
    00085   INDUSTRYBEH_PRODCALLBACK_RANDOM   = 1 << 15,
    00086   INDUSTRYBEH_NOBUILT_MAPCREATION   = 1 << 16,
    00087   INDUSTRYBEH_CANCLOSE_LASTINSTANCE = 1 << 17,
    00088 };
    00089
    00090
    00091 DECLARE_ENUM_AS_BIT_SET(IndustryBehaviour);
    00092
    00093 DECLARE_OLD_POOL(Industry, Industry, 3, 8000)
    00094
    00095
    00098 struct Industry : PoolItem<Industry, IndustryID, &_Industry_pool> {
    00099   typedef PersistentStorageArray<uint32, 16> PersistentStorage;
    00100
    00101   TileIndex xy;
    00102   byte width;
    00103   byte height;
    00104   const Town *town;
    00105   CargoID produced_cargo[2];
    00106   uint16 produced_cargo_waiting[2];
    00107   uint16 incoming_cargo_waiting[3];
    00108   byte production_rate[2];
    00109   byte prod_level;
    00110   CargoID accepts_cargo[3];
    00111   uint16 this_month_production[2];
    00112   uint16 this_month_transported[2];
    00113   byte last_month_pct_transported[2];
    00114   uint16 last_month_production[2];
    00115   uint16 last_month_transported[2];
    00116   uint16 counter;
    00117
    00118   IndustryType type;
    00119   OwnerByte owner;
    00120   byte random_colour;
    00121   Year last_prod_year;
    00122   byte was_cargo_delivered;
    00123
    00124   OwnerByte founder;
    00125   Date construction_date;
    00126   uint8 construction_type;
    00127   Date last_cargo_accepted_at;
    00128   byte selected_layout;
    00129
    00130   byte random_triggers;
    00131   uint16 random;
    00132
    00133   PersistentStorage psa;
    00134
    00135   Industry(TileIndex tile = INVALID_TILE) : xy(tile) {}
    00136   ~Industry();
    00137
    00138   inline bool IsValid() const { return this->xy != INVALID_TILE; }
    00139 };
    00140
    00141 struct IndustryTileTable {
    00142   TileIndexDiffC ti;
    00143   IndustryGfx gfx;
    00144 };
    00145
    00147 struct GRFFileProps {
    00148   uint16 subst_id;
    00149   uint16 local_id;
    00150   struct SpriteGroup *spritegroup;
    00151   const struct GRFFile *grffile;
    00152   uint16 override;
    00153 };
    00154
    00158 struct IndustrySpec {
    00159   const IndustryTileTable *const *table;
    00160   byte num_table;
    00161   uint8 cost_multiplier;
    00162   uint32 removal_cost_multiplier;
    00163   uint16 raw_industry_cost_multiplier;
    00164   uint32 prospecting_chance;
    00165   IndustryType conflicting[3];
    00166   byte check_proc;
    00167   CargoID produced_cargo[2];
    00168   byte production_rate[2];
    00169   byte minimal_cargo;
    00170
    00171   CargoID accepts_cargo[3];
    00172   uint16 input_cargo_multiplier[3][2];
    00173   IndustryLifeType life_type;
    00174   byte climate_availability;
    00175   IndustryBehaviour behaviour;
    00176   byte map_colour;
    00177   StringID name;
    00178   StringID new_industry_text;
    00179   StringID closure_text;
    00180   StringID production_up_text;
    00181   StringID production_down_text;
    00182   StringID station_name;
    00183   byte appear_ingame[NUM_LANDSCAPE];
    00184   byte appear_creation[NUM_LANDSCAPE];
    00185   uint8 number_of_sounds;
    00186   const uint8 *random_sounds;
    00187   /* Newgrf data */
    00188   uint16 callback_flags;
    00189   uint8 cleanup_flag;
    00190   bool enabled;
    00191   struct GRFFileProps grf_prop;
    00192
    00197   bool IsRawIndustry() const;
    00198
    00203   Money GetConstructionCost() const;
    00204
    00211   Money GetRemovalCost() const;
    00212 };
    00213
    00217 struct IndustryTileSpec {
    00218   CargoID accepts_cargo[3];
    00219   uint8 acceptance[3];
    00220   Slope slopes_refused;
    00221   byte anim_production;
    00222   byte anim_next;
    00223   bool anim_state;
    00224
    00225   /* Newgrf data */
    00226   uint8 callback_flags;
    00227   uint16 animation_info;
    00228   uint8 animation_speed;
    00229   uint8 animation_triggers;
    00230   uint8 animation_special_flags;
    00231   bool enabled;
    00232   struct GRFFileProps grf_prop;
    00233 };
    00234
    00235 /* industry_cmd.cpp*/
    00236 const IndustrySpec *GetIndustrySpec(IndustryType thistype);
    00237 const IndustryTileSpec *GetIndustryTileSpec(IndustryGfx gfx);
    00238 void ResetIndustries();
    00239 void PlantRandomFarmField(const Industry *i);
    00240
    00241 void ReleaseDisastersTargetingIndustry(IndustryID);
    00242
    00243 /* writable arrays of specs */
    00244 extern IndustrySpec _industry_specs[NUM_INDUSTRYTYPES];
    00245 extern IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES];
    00246
    00247 static inline IndustryGfx GetTranslatedIndustryTileID(IndustryGfx gfx)
    00248 {
    00249   /* the 0xFF should be GFX_WATERTILE_SPECIALCHECK but for reasons of include mess,
    00250    * we'll simplify the writing.
    00251    * Basically, the first test is required since the GFX_WATERTILE_SPECIALCHECK value
    00252    * will never be assigned as a tile index and is only required in order to do some
    00253    * tests while building the industry (as in WATER REQUIRED */
    00254   if (gfx != 0xFF) {
    00255     assert(gfx < INVALID_INDUSTRYTILE);
    00256     const IndustryTileSpec *it = &_industry_tile_specs[gfx];
    00257     return it->grf_prop.override == INVALID_INDUSTRYTILE ? gfx : it->grf_prop.override;
    00258   } else {
    00259     return gfx;
    00260   }
    00261 }
    00262
    00263 /* smallmap_gui.cpp */
    00264 void BuildIndustriesLegend();
    00265 /* industry_cmd.cpp */
    00266 void SetIndustryDailyChanges();
    00267
    00273 static inline bool IsValidIndustryID(IndustryID index)
    00274 {
    00275   return index < GetIndustryPoolSize() && GetIndustry(index)->IsValid();
    00276 }
    00277
    00278
    00279 static inline IndustryID GetMaxIndustryIndex()
    00280 {
    00281   /* TODO - This isn't the real content of the function, but
    00282    *  with the new pool-system this will be replaced with one that
    00283    *  _really_ returns the highest index. Now it just returns
    00284    *  the next safe value we are sure about everything is below.
    00285    */
    00286   return GetIndustryPoolSize() - 1;
    00287 }
    00288
    00289 extern int _total_industries;  // general counter
    00290 extern uint16 _industry_counts[NUM_INDUSTRYTYPES]; // Number of industries per type ingame
    00291
    00292 static inline uint GetNumIndustries()
    00293 {
    00294   return _total_industries;
    00295 }
    00296
    00300 static inline void IncIndustryTypeCount(IndustryType type)
    00301 {
    00302   assert(type < INVALID_INDUSTRYTYPE);
    00303   _industry_counts[type]++;
    00304   _total_industries++;
    00305 }
    00306
    00310 static inline void DecIndustryTypeCount(IndustryType type)
    00311 {
    00312   assert(type < INVALID_INDUSTRYTYPE);
    00313   _industry_counts[type]--;
    00314   _total_industries--;
    00315 }
    00316
    00320 static inline uint8 GetIndustryTypeCount(IndustryType type)
    00321 {
    00322   assert(type < INVALID_INDUSTRYTYPE);
    00323   return min(_industry_counts[type], 0xFF); // callback expects only a byte, so cut it
    00324 }
    00325
    00328 static inline void ResetIndustryCounts()
    00329 {
    00330   _total_industries = 0;
    00331   memset(&_industry_counts, 0, sizeof(_industry_counts));
    00332 }
    00333
    00337 static inline Industry *GetRandomIndustry()
    00338 {
    00339   int num = RandomRange(GetNumIndustries());
    00340   IndustryID index = INVALID_INDUSTRY;
    00341
    00342   if (GetNumIndustries() == 0) return NULL;
    00343
    00344   while (num >= 0) {
    00345     num--;
    00346     index++;
    00347
    00348     /* Make sure we have a valid industry */
    00349     while (!IsValidIndustryID(index)) {
    00350       index++;
    00351       assert(index <= GetMaxIndustryIndex());
    00352     }
    00353   }
    00354
    00355   return GetIndustry(index);
    00356 }
    00357
    00358 #define FOR_ALL_INDUSTRIES_FROM(i, start) for (i = GetIndustry(start); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) if (i->IsValid())
    00359 #define FOR_ALL_INDUSTRIES(i) FOR_ALL_INDUSTRIES_FROM(i, 0)
    00360
    00361 static const uint8 IT_INVALID = 255;
    00362
    00363 #endif /* INDUSTRY_H */