newgrf_debug_data.h

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