newgrf_debug_data.h

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 /* Helper for filling property tables */
00013 #define NIP(prop, base, variable, type, name) { name, cpp_offsetof(base, variable), cpp_sizeof(base, variable), prop, type }
00014 #define NIP_END() { NULL, 0, 0, 0, 0 }
00015 
00016 /* Helper for filling callback tables */
00017 #define NIC(cb_id, base, variable, bit) { #cb_id, cpp_offsetof(base, variable), cpp_sizeof(base, variable), bit, cb_id }
00018 #define NIC_END() { NULL, 0, 0, 0, 0 }
00019 
00020 /* Helper for filling variable tables */
00021 #define NIV(var, name) { name, var }
00022 #define NIV_END() { NULL, 0 }
00023 
00024 
00025 /*** NewGRF Vehicles ***/
00026 
00027 #define NICV(cb_id, bit) NIC(cb_id, Engine, info.callback_mask, bit)
00028 static const NICallback _nic_vehicles[] = {
00029   NICV(CBID_VEHICLE_VISUAL_EFFECT,         CBM_VEHICLE_VISUAL_EFFECT),
00030   NICV(CBID_VEHICLE_LENGTH,                CBM_VEHICLE_LENGTH),
00031   NICV(CBID_VEHICLE_LOAD_AMOUNT,           CBM_VEHICLE_LOAD_AMOUNT),
00032   NICV(CBID_VEHICLE_REFIT_CAPACITY,        CBM_VEHICLE_REFIT_CAPACITY),
00033   NICV(CBID_VEHICLE_ARTIC_ENGINE,          CBM_VEHICLE_ARTIC_ENGINE),
00034   NICV(CBID_VEHICLE_CARGO_SUFFIX,          CBM_VEHICLE_CARGO_SUFFIX),
00035   NICV(CBID_TRAIN_ALLOW_WAGON_ATTACH,      CBM_NO_BIT),
00036   NICV(CBID_VEHICLE_ADDITIONAL_TEXT,       CBM_NO_BIT),
00037   NICV(CBID_VEHICLE_COLOUR_MAPPING,        CBM_VEHICLE_COLOUR_REMAP),
00038   NICV(CBID_VEHICLE_START_STOP_CHECK,      CBM_NO_BIT),
00039   NICV(CBID_VEHICLE_32DAY_CALLBACK,        CBM_NO_BIT),
00040   NICV(CBID_VEHICLE_SOUND_EFFECT,          CBM_VEHICLE_SOUND_EFFECT),
00041   NICV(CBID_VEHICLE_AUTOREPLACE_SELECTION, CBM_NO_BIT),
00042   NICV(CBID_VEHICLE_MODIFY_PROPERTY,       CBM_NO_BIT),
00043   NIC_END()
00044 };
00045 
00046 
00047 static const NIVariable _niv_vehicles[] = {
00048   NIV(0x40, "position in consist and length"),
00049   NIV(0x41, "position and length of chain of same vehicles"),
00050   NIV(0x42, "transported cargo types"),
00051   NIV(0x43, "player info"),
00052   NIV(0x44, "aircraft info"),
00053   NIV(0x45, "curvature info"),
00054   NIV(0x46, "motion counter"),
00055   NIV(0x47, "vehicle cargo info"),
00056   NIV(0x48, "vehicle type info"),
00057   NIV(0x49, "year of construction"),
00058   NIV(0x4A, "current rail type info"),
00059   NIV(0x60, "count vehicle id occurrences"),
00060   NIV_END()
00061 };
00062 
00063 class NIHVehicle : public NIHelper {
00064   bool IsInspectable(uint index) const                 { return Vehicle::Get(index)->GetGRF() != NULL; }
00065   uint GetParent(uint index) const                     { const Vehicle *first = Vehicle::Get(index)->First(); return GetInspectWindowNumber(GetGrfSpecFeature(first->type), first->index); }
00066   const void *GetInstance(uint index)const             { return Vehicle::Get(index); }
00067   const void *GetSpec(uint index) const                { return Vehicle::Get(index)->GetEngine(); }
00068   void SetStringParameters(uint index) const           { this->SetSimpleStringParameters(STR_VEHICLE_NAME, index); }
00069   uint32 GetGRFID(uint index) const                    { return Vehicle::Get(index)->GetGRFID(); }
00070   void Resolve(ResolverObject *ro, uint32 index) const { extern void GetVehicleResolver(ResolverObject *ro, uint index); GetVehicleResolver(ro, index); }
00071 };
00072 
00073 static const NIFeature _nif_vehicle = {
00074   NULL,
00075   _nic_vehicles,
00076   _niv_vehicles,
00077   new NIHVehicle(),
00078 };
00079 
00080 
00081 /*** NewGRF station (tiles) ***/
00082 
00083 #define NICS(cb_id, bit) NIC(cb_id, StationSpec, callback_mask, bit)
00084 static const NICallback _nic_stations[] = {
00085   NICS(CBID_STATION_AVAILABILITY,     CBM_STATION_AVAIL),
00086   NICS(CBID_STATION_SPRITE_LAYOUT,    CBM_NO_BIT),
00087   NICS(CBID_STATION_TILE_LAYOUT,      CBM_STATION_SPRITE_LAYOUT),
00088   NICS(CBID_STATION_ANIM_START_STOP,  CBM_NO_BIT),
00089   NICS(CBID_STATION_ANIM_NEXT_FRAME,  CBM_STATION_ANIMATION_NEXT_FRAME),
00090   NICS(CBID_STATION_ANIMATION_SPEED,  CBM_STATION_ANIMATION_SPEED),
00091   NICS(CBID_STATION_LAND_SLOPE_CHECK, CBM_STATION_SLOPE_CHECK),
00092   NIC_END()
00093 };
00094 
00095 static const NIVariable _niv_stations[] = {
00096   NIV(0x40, "platform info and relative position"),
00097   NIV(0x41, "platform info and relative position for individually built sections"),
00098   NIV(0x42, "terrain and track type"),
00099   NIV(0x43, "player info"),
00100   NIV(0x44, "path signalling info"),
00101   NIV(0x45, "rail continuation info"),
00102   NIV(0x46, "platform info and relative position from middle"),
00103   NIV(0x47, "platform info and relative position from middle for individually built sections"),
00104   NIV(0x48, "bitmask of accepted cargoes"),
00105   NIV(0x49, "platform info and relative position of same-direction section"),
00106   NIV(0x4A, "current animation frame"),
00107   NIV(0x60, "amount of cargo waiting"),
00108   NIV(0x61, "time since last cargo pickup"),
00109   NIV(0x62, "rating of cargo"),
00110   NIV(0x63, "time spent on route"),
00111   NIV(0x64, "information about last vehicle picking cargo up"),
00112   NIV(0x65, "amount of cargo acceptance"),
00113   NIV(0x66, "animation frame of nearby tile"),
00114   NIV(0x67, "land info of nearby tiles"),
00115   NIV(0x68, "station info of nearby tiles"),
00116   NIV(0x69, "information about cargo accepted in the past"),
00117   NIV_END()
00118 };
00119 
00120 class NIHStation : public NIHelper {
00121   bool IsInspectable(uint index) const                 { return GetStationSpec(index) != NULL; }
00122   uint GetParent(uint index) const                     { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); }
00123   const void *GetInstance(uint index)const             { return NULL; }
00124   const void *GetSpec(uint index) const                { return GetStationSpec(index); }
00125   void SetStringParameters(uint index) const           { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); }
00126   uint32 GetGRFID(uint index) const                    { return (this->IsInspectable(index)) ? GetStationSpec(index)->grf_prop.grffile->grfid : 0; }
00127   void Resolve(ResolverObject *ro, uint32 index) const { extern void GetStationResolver(ResolverObject *ro, uint index); GetStationResolver(ro, index); }
00128 };
00129 
00130 static const NIFeature _nif_station = {
00131   NULL,
00132   _nic_stations,
00133   _niv_stations,
00134   new NIHStation(),
00135 };
00136 
00137 
00138 /*** NewGRF house tiles ***/
00139 
00140 #define NICH(cb_id, bit) NIC(cb_id, HouseSpec, callback_mask, bit)
00141 static const NICallback _nic_house[] = {
00142   NICH(CBID_HOUSE_ALLOW_CONSTRUCTION,        CBM_HOUSE_ALLOW_CONSTRUCTION),
00143   NICH(CBID_HOUSE_ANIMATION_NEXT_FRAME,      CBM_HOUSE_ANIMATION_NEXT_FRAME),
00144   NICH(CBID_HOUSE_ANIMATION_START_STOP,      CBM_HOUSE_ANIMATION_START_STOP),
00145   NICH(CBID_HOUSE_CONSTRUCTION_STATE_CHANGE, CBM_HOUSE_CONSTRUCTION_STATE_CHANGE),
00146   NICH(CBID_HOUSE_COLOUR,                    CBM_HOUSE_COLOUR),
00147   NICH(CBID_HOUSE_CARGO_ACCEPTANCE,          CBM_HOUSE_CARGO_ACCEPTANCE),
00148   NICH(CBID_HOUSE_ANIMATION_SPEED,           CBM_HOUSE_ANIMATION_SPEED),
00149   NICH(CBID_HOUSE_DESTRUCTION,               CBM_HOUSE_DESTRUCTION),
00150   NICH(CBID_HOUSE_ACCEPT_CARGO,              CBM_HOUSE_ACCEPT_CARGO),
00151   NICH(CBID_HOUSE_PRODUCE_CARGO,             CBM_HOUSE_PRODUCE_CARGO),
00152   NICH(CBID_HOUSE_DENY_DESTRUCTION,          CBM_HOUSE_DENY_DESTRUCTION),
00153   NICH(CBID_HOUSE_WATCHED_CARGO_ACCEPTED,    CBM_NO_BIT),
00154   NICH(CBID_HOUSE_CUSTOM_NAME,               CBM_NO_BIT),
00155   NICH(CBID_HOUSE_DRAW_FOUNDATIONS,          CBM_HOUSE_DRAW_FOUNDATIONS),
00156   NICH(CBID_HOUSE_AUTOSLOPE,                 CBM_HOUSE_AUTOSLOPE),
00157   NIC_END()
00158 };
00159 
00160 static const NIVariable _niv_house[] = {
00161   NIV(0x40, "construction state of tile and pseudo-random value"),
00162   NIV(0x41, "age of building in years"),
00163   NIV(0x42, "town zone"),
00164   NIV(0x43, "terrain type"),
00165   NIV(0x44, "building counts"),
00166   NIV(0x45, "town expansion bits"),
00167   NIV(0x46, "current animation frame"),
00168   NIV(0x47, "xy coordinate of the building"),
00169   NIV(0x60, "other building counts (old house type)"),
00170   NIV(0x61, "other building counts (new house type)"),
00171   NIV(0x62, "land info of nearby tiles"),
00172   NIV(0x63, "current animation frame of nearby house tile"),
00173   NIV(0x64, "cargo acceptance history of nearby stations"),
00174   NIV(0x65, "distance of nearest house matching a given criterion"),
00175   NIV(0x66, "class and ID of nearby house tile"),
00176   NIV(0x67, "GRFID of nearby house tile"),
00177   NIV_END()
00178 };
00179 
00180 class NIHHouse : public NIHelper {
00181   bool IsInspectable(uint index) const                 { return HouseSpec::Get(GetHouseType(index))->grf_prop.grffile != NULL; }
00182   uint GetParent(uint index) const                     { return GetInspectWindowNumber(GSF_FAKE_TOWNS, GetTownIndex(index)); }
00183   const void *GetInstance(uint index)const             { return NULL; }
00184   const void *GetSpec(uint index) const                { return HouseSpec::Get(GetHouseType(index)); }
00185   void SetStringParameters(uint index) const           { this->SetObjectAtStringParameters(STR_TOWN_NAME, GetTownIndex(index), index); }
00186   uint32 GetGRFID(uint index) const                    { return (this->IsInspectable(index)) ? HouseSpec::Get(GetHouseType(index))->grf_prop.grffile->grfid : 0; }
00187   void Resolve(ResolverObject *ro, uint32 index) const { extern void GetHouseResolver(ResolverObject *ro, uint index); GetHouseResolver(ro, index); }
00188 };
00189 
00190 static const NIFeature _nif_house = {
00191   NULL,
00192   _nic_house,
00193   _niv_house,
00194   new NIHHouse(),
00195 };
00196 
00197 
00198 /*** NewGRF industry tiles ***/
00199 
00200 #define NICIT(cb_id, bit) NIC(cb_id, IndustryTileSpec, callback_mask, bit)
00201 static const NICallback _nic_industrytiles[] = {
00202   NICIT(CBID_INDTILE_ANIM_START_STOP,  CBM_NO_BIT),
00203   NICIT(CBID_INDTILE_ANIM_NEXT_FRAME,  CBM_INDT_ANIM_NEXT_FRAME),
00204   NICIT(CBID_INDTILE_ANIMATION_SPEED,  CBM_INDT_ANIM_SPEED),
00205   NICIT(CBID_INDTILE_CARGO_ACCEPTANCE, CBM_INDT_CARGO_ACCEPTANCE),
00206   NICIT(CBID_INDTILE_ACCEPT_CARGO,     CBM_INDT_ACCEPT_CARGO),
00207   NICIT(CBID_INDTILE_SHAPE_CHECK,      CBM_INDT_SHAPE_CHECK),
00208   NICIT(CBID_INDTILE_DRAW_FOUNDATIONS, CBM_INDT_DRAW_FOUNDATIONS),
00209   NICIT(CBID_INDTILE_AUTOSLOPE,        CBM_INDT_AUTOSLOPE),
00210   NIC_END()
00211 };
00212 
00213 static const NIVariable _niv_industrytiles[] = {
00214   NIV(0x40, "construction state of tile"),
00215   NIV(0x41, "ground type"),
00216   NIV(0x42, "current town zone in nearest town"),
00217   NIV(0x43, "relative position"),
00218   NIV(0x44, "animation frame"),
00219   NIV(0x60, "land info of nearby tiles"),
00220   NIV(0x61, "animation stage of nearby tiles"),
00221   NIV(0x62, "get industry or airport tile ID at offset"),
00222   NIV_END()
00223 };
00224 
00225 class NIHIndustryTile : public NIHelper {
00226   bool IsInspectable(uint index) const                 { return GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile != NULL; }
00227   uint GetParent(uint index) const                     { return GetInspectWindowNumber(GSF_INDUSTRIES, GetIndustryIndex(index)); }
00228   const void *GetInstance(uint index)const             { return NULL; }
00229   const void *GetSpec(uint index) const                { return GetIndustryTileSpec(GetIndustryGfx(index)); }
00230   void SetStringParameters(uint index) const           { this->SetObjectAtStringParameters(STR_INDUSTRY_NAME, GetIndustryIndex(index), index); }
00231   uint32 GetGRFID(uint index) const                    { return (this->IsInspectable(index)) ? GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile->grfid : 0; }
00232   void Resolve(ResolverObject *ro, uint32 index) const { extern void GetIndustryTileResolver(ResolverObject *ro, uint index); GetIndustryTileResolver(ro, index); }
00233 };
00234 
00235 static const NIFeature _nif_industrytile = {
00236   NULL,
00237   _nic_industrytiles,
00238   _niv_industrytiles,
00239   new NIHIndustryTile(),
00240 };
00241 
00242 
00243 /*** NewGRF industries ***/
00244 
00245 static const NIProperty _nip_industries[] = {
00246   NIP(0x10, Industry, produced_cargo[0], NIT_CARGO, "produced cargo 0"),
00247   NIP(0x10, Industry, produced_cargo[1], NIT_CARGO, "produced cargo 1"),
00248   NIP(0x11, Industry, accepts_cargo[0],  NIT_CARGO, "accepted cargo 0"),
00249   NIP(0x11, Industry, accepts_cargo[1],  NIT_CARGO, "accepted cargo 1"),
00250   NIP(0x11, Industry, accepts_cargo[2],  NIT_CARGO, "accepted cargo 2"),
00251   NIP_END()
00252 };
00253 
00254 #define NICI(cb_id, bit) NIC(cb_id, IndustrySpec, callback_mask, bit)
00255 static const NICallback _nic_industries[] = {
00256   NICI(CBID_INDUSTRY_PROBABILITY,          CBM_IND_PROBABILITY),
00257   NICI(CBID_INDUSTRY_LOCATION,             CBM_IND_LOCATION),
00258   NICI(CBID_INDUSTRY_PRODUCTION_CHANGE,    CBM_IND_PRODUCTION_CHANGE),
00259   NICI(CBID_INDUSTRY_MONTHLYPROD_CHANGE,   CBM_IND_MONTHLYPROD_CHANGE),
00260   NICI(CBID_INDUSTRY_CARGO_SUFFIX,         CBM_IND_CARGO_SUFFIX),
00261   NICI(CBID_INDUSTRY_FUND_MORE_TEXT,       CBM_IND_FUND_MORE_TEXT),
00262   NICI(CBID_INDUSTRY_WINDOW_MORE_TEXT,     CBM_IND_WINDOW_MORE_TEXT),
00263   NICI(CBID_INDUSTRY_SPECIAL_EFFECT,       CBM_IND_SPECIAL_EFFECT),
00264   NICI(CBID_INDUSTRY_REFUSE_CARGO,         CBM_IND_REFUSE_CARGO),
00265   NICI(CBID_INDUSTRY_DECIDE_COLOUR,        CBM_IND_DECIDE_COLOUR),
00266   NICI(CBID_INDUSTRY_INPUT_CARGO_TYPES,    CBM_IND_INPUT_CARGO_TYPES),
00267   NICI(CBID_INDUSTRY_OUTPUT_CARGO_TYPES,   CBM_IND_OUTPUT_CARGO_TYPES),
00268   NICI(CBID_INDUSTRY_PROD_CHANGE_BUILD,    CBM_IND_PROD_CHANGE_BUILD),
00269   NIC_END()
00270 };
00271 
00272 static const NIVariable _niv_industries[] = {
00273   NIV(0x40, "waiting cargo 0"),
00274   NIV(0x41, "waiting cargo 1"),
00275   NIV(0x42, "waiting cargo 2"),
00276   NIV(0x43, "distance to closest dry/land tile"),
00277   NIV(0x44, "layout number"),
00278   NIV(0x45, "player info"),
00279   NIV(0x46, "industry construction date"),
00280   NIV(0x60, "get industry tile ID at offset"),
00281   NIV(0x61, "get random tile bits at offset"),
00282   NIV(0x62, "land info of nearby tiles"),
00283   NIV(0x63, "animation stage of nearby tiles"),
00284   NIV(0x64, "distance on nearest industry with given type"),
00285   NIV(0x65, "get town zone and Manhattan distance of closest town"),
00286   NIV(0x66, "get square of Euclidean distance of closes town"),
00287   NIV(0x67, "count of industry and distance of closest instance"),
00288   NIV(0x68, "count of industry and distance of closest instance with layout filter"),
00289   NIV_END()
00290 };
00291 
00292 class NIHIndustry : public NIHelper {
00293   bool IsInspectable(uint index) const                 { return GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile != NULL; }
00294   uint GetParent(uint index) const                     { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Industry::Get(index)->town->index); }
00295   const void *GetInstance(uint index)const             { return Industry::Get(index); }
00296   const void *GetSpec(uint index) const                { return GetIndustrySpec(Industry::Get(index)->type); }
00297   void SetStringParameters(uint index) const           { this->SetSimpleStringParameters(STR_INDUSTRY_NAME, index); }
00298   uint32 GetGRFID(uint index) const                    { return (this->IsInspectable(index)) ? GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile->grfid : 0; }
00299   void Resolve(ResolverObject *ro, uint32 index) const { extern void GetIndustryResolver(ResolverObject *ro, uint index); GetIndustryResolver(ro, index); }
00300   uint GetPSASize(uint index, uint32 grfid) const      { return cpp_lengthof(PersistentStorage, storage); }
00301 
00302   const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const
00303   {
00304     const Industry *i = (const Industry *)this->GetInstance(index);
00305     if (i->psa == NULL) return NULL;
00306     return (int32 *)(&i->psa->storage);
00307   }
00308 };
00309 
00310 static const NIFeature _nif_industry = {
00311   _nip_industries,
00312   _nic_industries,
00313   _niv_industries,
00314   new NIHIndustry(),
00315 };
00316 
00317 
00318 /*** NewGRF objects ***/
00319 
00320 #define NICO(cb_id, bit) NIC(cb_id, ObjectSpec, callback_mask, bit)
00321 static const NICallback _nic_objects[] = {
00322   NICO(CBID_OBJECT_LAND_SLOPE_CHECK,     CBM_OBJ_SLOPE_CHECK),
00323   NICO(CBID_OBJECT_ANIMATION_NEXT_FRAME, CBM_OBJ_ANIMATION_NEXT_FRAME),
00324   NICO(CBID_OBJECT_ANIMATION_START_STOP, CBM_NO_BIT),
00325   NICO(CBID_OBJECT_ANIMATION_SPEED,      CBM_OBJ_ANIMATION_SPEED),
00326   NICO(CBID_OBJECT_COLOUR,               CBM_OBJ_COLOUR),
00327   NICO(CBID_OBJECT_FUND_MORE_TEXT,       CBM_OBJ_FUND_MORE_TEXT),
00328   NICO(CBID_OBJECT_AUTOSLOPE,            CBM_OBJ_AUTOSLOPE),
00329   NIC_END()
00330 };
00331 
00332 static const NIVariable _niv_objects[] = {
00333   NIV(0x40, "relative position"),
00334   NIV(0x41, "tile information"),
00335   NIV(0x42, "construction date"),
00336   NIV(0x43, "animation counter"),
00337   NIV(0x44, "object founder"),
00338   NIV(0x45, "get town zone and Manhattan distance of closest town"),
00339   NIV(0x46, "get square of Euclidean distance of closes town"),
00340   NIV(0x47, "colour"),
00341   NIV(0x48, "view"),
00342   NIV(0x60, "get object ID at offset"),
00343   NIV(0x61, "get random tile bits at offset"),
00344   NIV(0x62, "land info of nearby tiles"),
00345   NIV(0x63, "animation stage of nearby tiles"),
00346   NIV(0x64, "distance on nearest object with given type"),
00347   NIV_END()
00348 };
00349 
00350 class NIHObject : public NIHelper {
00351   bool IsInspectable(uint index) const                 { return ObjectSpec::GetByTile(index)->grf_prop.grffile != NULL; }
00352   uint GetParent(uint index) const                     { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Object::GetByTile(index)->town->index); }
00353   const void *GetInstance(uint index)const             { return Object::GetByTile(index); }
00354   const void *GetSpec(uint index) const                { return ObjectSpec::GetByTile(index); }
00355   void SetStringParameters(uint index) const           { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT, INVALID_STRING_ID, index); }
00356   uint32 GetGRFID(uint index) const                    { return (this->IsInspectable(index)) ? ObjectSpec::GetByTile(index)->grf_prop.grffile->grfid : 0; }
00357   void Resolve(ResolverObject *ro, uint32 index) const { extern void GetObjectResolver(ResolverObject *ro, uint index); GetObjectResolver(ro, index); }
00358 };
00359 
00360 static const NIFeature _nif_object = {
00361   NULL,
00362   _nic_objects,
00363   _niv_objects,
00364   new NIHObject(),
00365 };
00366 
00367 
00368 /*** NewGRF rail types ***/
00369 
00370 static const NIVariable _niv_railtypes[] = {
00371   NIV(0x40, "terrain type"),
00372   NIV(0x41, "enhanced tunnels"),
00373   NIV(0x42, "level crossing status"),
00374   NIV_END()
00375 };
00376 
00377 class NIHRailType : public NIHelper {
00378   bool IsInspectable(uint index) const                 { return true; }
00379   uint GetParent(uint index) const                     { return UINT32_MAX; }
00380   const void *GetInstance(uint index)const             { return NULL; }
00381   const void *GetSpec(uint index) const                { return NULL; }
00382   void SetStringParameters(uint index) const           { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); }
00383   uint32 GetGRFID(uint index) const                    { return 0; }
00384   void Resolve(ResolverObject *ro, uint32 index) const { extern void GetRailTypeResolver(ResolverObject *ro, uint index); GetRailTypeResolver(ro, index); }
00385 };
00386 
00387 static const NIFeature _nif_railtype = {
00388   NULL,
00389   NULL,
00390   _niv_railtypes,
00391   new NIHRailType(),
00392 };
00393 
00394 
00395 /*** NewGRF airport tiles ***/
00396 
00397 #define NICAT(cb_id, bit) NIC(cb_id, AirportTileSpec, callback_mask, bit)
00398 static const NICallback _nic_airporttiles[] = {
00399   NICAT(CBID_AIRPTILE_DRAW_FOUNDATIONS, CBM_AIRT_DRAW_FOUNDATIONS),
00400   NICAT(CBID_AIRPTILE_ANIM_START_STOP,  CBM_NO_BIT),
00401   NICAT(CBID_AIRPTILE_ANIM_NEXT_FRAME,  CBM_AIRT_ANIM_NEXT_FRAME),
00402   NICAT(CBID_AIRPTILE_ANIMATION_SPEED,  CBM_AIRT_ANIM_SPEED),
00403   NIC_END()
00404 };
00405 
00406 class NIHAirportTile : public NIHelper {
00407   bool IsInspectable(uint index) const                 { return AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile != NULL; }
00408   uint GetParent(uint index) const                     { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); }
00409   const void *GetInstance(uint index)const             { return NULL; }
00410   const void *GetSpec(uint index) const                { return AirportTileSpec::Get(GetAirportGfx(index)); }
00411   void SetStringParameters(uint index) const           { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); }
00412   uint32 GetGRFID(uint index) const                    { return (this->IsInspectable(index)) ? AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile->grfid : 0; }
00413   void Resolve(ResolverObject *ro, uint32 index) const { extern void GetAirportTileTypeResolver(ResolverObject *ro, uint index); GetAirportTileTypeResolver(ro, index); }
00414 };
00415 
00416 static const NIFeature _nif_airporttile = {
00417   NULL,
00418   _nic_airporttiles,
00419   _niv_industrytiles, // Yes, they share this (at least now)
00420   new NIHAirportTile(),
00421 };
00422 
00423 
00424 /*** NewGRF towns ***/
00425 
00426 static const NIVariable _niv_towns[] = {
00427   NIV(0x40, "larger town effect on this town"),
00428   NIV(0x41, "town index"),
00429   NIV(0x82, "population"),
00430   NIV(0x94, "zone radius 0"),
00431   NIV(0x96, "zone radius 1"),
00432   NIV(0x98, "zone radius 2"),
00433   NIV(0x9A, "zone radius 3"),
00434   NIV(0x9C, "zone radius 4"),
00435   NIV(0xB6, "number of buildings"),
00436   NIV_END()
00437 };
00438 
00439 class NIHTown : public NIHelper {
00440   bool IsInspectable(uint index) const                 { return Town::IsValidID(index); }
00441   uint GetParent(uint index) const                     { return UINT32_MAX; }
00442   const void *GetInstance(uint index)const             { return Town::Get(index); }
00443   const void *GetSpec(uint index) const                { return NULL; }
00444   void SetStringParameters(uint index) const           { this->SetSimpleStringParameters(STR_TOWN_NAME, index); }
00445   uint32 GetGRFID(uint index) const                    { return 0; }
00446   uint Resolve(uint index, uint var, uint param, bool *avail) const { return TownGetVariable(var, param, avail, Town::Get(index), NULL); }
00447   bool PSAWithParameter() const                        { return true; }
00448   uint GetPSASize(uint index, uint32 grfid) const      { return cpp_lengthof(PersistentStorage, storage); }
00449 
00450   const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const
00451   {
00452     Town *t = Town::Get(index);
00453 
00454     std::list<PersistentStorage *>::iterator iter;
00455     for (iter = t->psa_list.begin(); iter != t->psa_list.end(); iter++) {
00456       if ((*iter)->grfid == grfid) return (int32 *)(&(*iter)->storage[0]);
00457     }
00458 
00459     return NULL;
00460   }
00461 };
00462 
00463 static const NIFeature _nif_town = {
00464   NULL,
00465   NULL,
00466   _niv_towns,
00467   new NIHTown(),
00468 };
00469 
00471 static const NIFeature * const _nifeatures[] = {
00472   &_nif_vehicle,      // GSF_TRAINS
00473   &_nif_vehicle,      // GSF_ROADVEHICLES
00474   &_nif_vehicle,      // GSF_SHIPS
00475   &_nif_vehicle,      // GSF_AIRCRAFT
00476   &_nif_station,      // GSF_STATIONS
00477   NULL,               // GSF_CANALS (no callbacks/action2 implemented)
00478   NULL,               // GSF_BRIDGES (no callbacks/action2)
00479   &_nif_house,        // GSF_HOUSES
00480   NULL,               // GSF_GLOBALVAR (has no "physical" objects)
00481   &_nif_industrytile, // GSF_INDUSTRYTILES
00482   &_nif_industry,     // GSF_INDUSTRIES
00483   NULL,               // GSF_CARGOES (has no "physical" objects)
00484   NULL,               // GSF_SOUNDFX (has no "physical" objects)
00485   NULL,               // GSF_AIRPORTS (feature not implemented)
00486   NULL,               // GSF_SIGNALS (feature not implemented)
00487   &_nif_object,       // GSF_OBJECTS
00488   &_nif_railtype,     // GSF_RAILTYPES
00489   &_nif_airporttile,  // GSF_AIRPORTTILES
00490   &_nif_town,         // GSF_FAKE_TOWNS
00491 };
00492 assert_compile(lengthof(_nifeatures) == GSF_FAKE_END);