# newgrf_debug_data.h

Go to the documentation of this file.

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