1 /* 2 * This file is part of OpenTTD. 3 * 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. 4 * 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. 5 * 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/>. 6 */ 7 8 /** @file newgrf_debug_data.h Data 'tables' for NewGRF debugging. */ 9 10 #include "../newgrf_house.h" 11 #include "../newgrf_engine.h" 12 #include "../newgrf_roadtype.h" 13 14 /* Helper for filling property tables */ 15 #define NIP(prop, base, variable, type, name) { name, [] (const void *b) -> const void * { return std::addressof(static_cast<const base *>(b)->variable); }, cpp_sizeof(base, variable), prop, type } 16 #define NIP_END() { nullptr, 0, 0, 0, 0 } 17 18 /* Helper for filling callback tables */ 19 #define NIC(cb_id, base, variable, bit) { #cb_id, [] (const void *b) -> const void * { return std::addressof(static_cast<const base *>(b)->variable); }, cpp_sizeof(base, variable), bit, cb_id } 20 #define NIC_END() { nullptr, 0, 0, 0, 0 } 21 22 /* Helper for filling variable tables */ 23 #define NIV(var, name) { name, var } 24 #define NIV_END() { nullptr, 0 } 25 26 27 /*** NewGRF Vehicles ***/ 28 29 #define NICV(cb_id, bit) NIC(cb_id, Engine, info.callback_mask, bit) 30 static const NICallback _nic_vehicles[] = { 31 NICV(CBID_VEHICLE_VISUAL_EFFECT, CBM_VEHICLE_VISUAL_EFFECT), 32 NICV(CBID_VEHICLE_LENGTH, CBM_VEHICLE_LENGTH), 33 NICV(CBID_VEHICLE_LOAD_AMOUNT, CBM_VEHICLE_LOAD_AMOUNT), 34 NICV(CBID_VEHICLE_REFIT_CAPACITY, CBM_VEHICLE_REFIT_CAPACITY), 35 NICV(CBID_VEHICLE_ARTIC_ENGINE, CBM_VEHICLE_ARTIC_ENGINE), 36 NICV(CBID_VEHICLE_CARGO_SUFFIX, CBM_VEHICLE_CARGO_SUFFIX), 37 NICV(CBID_TRAIN_ALLOW_WAGON_ATTACH, CBM_NO_BIT), 38 NICV(CBID_VEHICLE_ADDITIONAL_TEXT, CBM_NO_BIT), 39 NICV(CBID_VEHICLE_COLOUR_MAPPING, CBM_VEHICLE_COLOUR_REMAP), 40 NICV(CBID_VEHICLE_START_STOP_CHECK, CBM_NO_BIT), 41 NICV(CBID_VEHICLE_32DAY_CALLBACK, CBM_NO_BIT), 42 NICV(CBID_VEHICLE_SOUND_EFFECT, CBM_VEHICLE_SOUND_EFFECT), 43 NICV(CBID_VEHICLE_AUTOREPLACE_SELECTION, CBM_NO_BIT), 44 NICV(CBID_VEHICLE_MODIFY_PROPERTY, CBM_NO_BIT), 45 NIC_END() 46 }; 47 48 49 static const NIVariable _niv_vehicles[] = { 50 NIV(0x40, "position in consist and length"), 51 NIV(0x41, "position and length of chain of same vehicles"), 52 NIV(0x42, "transported cargo types"), 53 NIV(0x43, "player info"), 54 NIV(0x44, "aircraft info"), 55 NIV(0x45, "curvature info"), 56 NIV(0x46, "motion counter"), 57 NIV(0x47, "vehicle cargo info"), 58 NIV(0x48, "vehicle type info"), 59 NIV(0x49, "year of construction"), 60 NIV(0x4A, "current rail/road type info"), 61 NIV(0x4B, "long date of last service"), 62 NIV(0x4C, "current max speed"), 63 NIV(0x4D, "position in articulated vehicle"), 64 NIV(0x60, "count vehicle id occurrences"), 65 // 0x61 not useful, since it requires register 0x10F 66 NIV(0x62, "curvature/position difference to other vehicle"), 67 NIV(0x63, "tile compatibility wrt. track-type"), 68 NIV_END() 69 }; 70 71 class NIHVehicle : public NIHelper { IsInspectable(uint index)72 bool IsInspectable(uint index) const override { return Vehicle::Get(index)->GetGRF() != nullptr; } GetParent(uint index)73 uint GetParent(uint index) const override { const Vehicle *first = Vehicle::Get(index)->First(); return GetInspectWindowNumber(GetGrfSpecFeature(first->type), first->index); } GetInstance(uint index)74 const void *GetInstance(uint index)const override { return Vehicle::Get(index); } GetSpec(uint index)75 const void *GetSpec(uint index) const override { return Vehicle::Get(index)->GetEngine(); } SetStringParameters(uint index)76 void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_VEHICLE_NAME, index); } GetGRFID(uint index)77 uint32 GetGRFID(uint index) const override { return Vehicle::Get(index)->GetGRFID(); } 78 Resolve(uint index,uint var,uint param,bool * avail)79 uint Resolve(uint index, uint var, uint param, bool *avail) const override 80 { 81 Vehicle *v = Vehicle::Get(index); 82 VehicleResolverObject ro(v->engine_type, v, VehicleResolverObject::WO_CACHED); 83 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 84 } 85 }; 86 87 static const NIFeature _nif_vehicle = { 88 nullptr, 89 _nic_vehicles, 90 _niv_vehicles, 91 new NIHVehicle(), 92 }; 93 94 95 /*** NewGRF station (tiles) ***/ 96 97 #define NICS(cb_id, bit) NIC(cb_id, StationSpec, callback_mask, bit) 98 static const NICallback _nic_stations[] = { 99 NICS(CBID_STATION_AVAILABILITY, CBM_STATION_AVAIL), 100 NICS(CBID_STATION_SPRITE_LAYOUT, CBM_STATION_SPRITE_LAYOUT), 101 NICS(CBID_STATION_TILE_LAYOUT, CBM_NO_BIT), 102 NICS(CBID_STATION_ANIM_START_STOP, CBM_NO_BIT), 103 NICS(CBID_STATION_ANIM_NEXT_FRAME, CBM_STATION_ANIMATION_NEXT_FRAME), 104 NICS(CBID_STATION_ANIMATION_SPEED, CBM_STATION_ANIMATION_SPEED), 105 NICS(CBID_STATION_LAND_SLOPE_CHECK, CBM_STATION_SLOPE_CHECK), 106 NIC_END() 107 }; 108 109 static const NIVariable _niv_stations[] = { 110 NIV(0x40, "platform info and relative position"), 111 NIV(0x41, "platform info and relative position for individually built sections"), 112 NIV(0x42, "terrain and track type"), 113 NIV(0x43, "player info"), 114 NIV(0x44, "path signalling info"), 115 NIV(0x45, "rail continuation info"), 116 NIV(0x46, "platform info and relative position from middle"), 117 NIV(0x47, "platform info and relative position from middle for individually built sections"), 118 NIV(0x48, "bitmask of accepted cargoes"), 119 NIV(0x49, "platform info and relative position of same-direction section"), 120 NIV(0x4A, "current animation frame"), 121 NIV(0x60, "amount of cargo waiting"), 122 NIV(0x61, "time since last cargo pickup"), 123 NIV(0x62, "rating of cargo"), 124 NIV(0x63, "time spent on route"), 125 NIV(0x64, "information about last vehicle picking cargo up"), 126 NIV(0x65, "amount of cargo acceptance"), 127 NIV(0x66, "animation frame of nearby tile"), 128 NIV(0x67, "land info of nearby tiles"), 129 NIV(0x68, "station info of nearby tiles"), 130 NIV(0x69, "information about cargo accepted in the past"), 131 NIV(0x6A, "GRFID of nearby station tiles"), 132 NIV_END() 133 }; 134 135 class NIHStation : public NIHelper { IsInspectable(uint index)136 bool IsInspectable(uint index) const override { return GetStationSpec(index) != nullptr; } GetParent(uint index)137 uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); } GetInstance(uint index)138 const void *GetInstance(uint index)const override { return nullptr; } GetSpec(uint index)139 const void *GetSpec(uint index) const override { return GetStationSpec(index); } SetStringParameters(uint index)140 void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); } GetGRFID(uint index)141 uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetStationSpec(index)->grf_prop.grffile->grfid : 0; } 142 Resolve(uint index,uint var,uint param,bool * avail)143 uint Resolve(uint index, uint var, uint param, bool *avail) const override 144 { 145 StationResolverObject ro(GetStationSpec(index), Station::GetByTile(index), index); 146 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 147 } 148 }; 149 150 static const NIFeature _nif_station = { 151 nullptr, 152 _nic_stations, 153 _niv_stations, 154 new NIHStation(), 155 }; 156 157 158 /*** NewGRF house tiles ***/ 159 160 #define NICH(cb_id, bit) NIC(cb_id, HouseSpec, callback_mask, bit) 161 static const NICallback _nic_house[] = { 162 NICH(CBID_HOUSE_ALLOW_CONSTRUCTION, CBM_HOUSE_ALLOW_CONSTRUCTION), 163 NICH(CBID_HOUSE_ANIMATION_NEXT_FRAME, CBM_HOUSE_ANIMATION_NEXT_FRAME), 164 NICH(CBID_HOUSE_ANIMATION_START_STOP, CBM_HOUSE_ANIMATION_START_STOP), 165 NICH(CBID_HOUSE_CONSTRUCTION_STATE_CHANGE, CBM_HOUSE_CONSTRUCTION_STATE_CHANGE), 166 NICH(CBID_HOUSE_COLOUR, CBM_HOUSE_COLOUR), 167 NICH(CBID_HOUSE_CARGO_ACCEPTANCE, CBM_HOUSE_CARGO_ACCEPTANCE), 168 NICH(CBID_HOUSE_ANIMATION_SPEED, CBM_HOUSE_ANIMATION_SPEED), 169 NICH(CBID_HOUSE_DESTRUCTION, CBM_HOUSE_DESTRUCTION), 170 NICH(CBID_HOUSE_ACCEPT_CARGO, CBM_HOUSE_ACCEPT_CARGO), 171 NICH(CBID_HOUSE_PRODUCE_CARGO, CBM_HOUSE_PRODUCE_CARGO), 172 NICH(CBID_HOUSE_DENY_DESTRUCTION, CBM_HOUSE_DENY_DESTRUCTION), 173 NICH(CBID_HOUSE_WATCHED_CARGO_ACCEPTED, CBM_NO_BIT), 174 NICH(CBID_HOUSE_CUSTOM_NAME, CBM_NO_BIT), 175 NICH(CBID_HOUSE_DRAW_FOUNDATIONS, CBM_HOUSE_DRAW_FOUNDATIONS), 176 NICH(CBID_HOUSE_AUTOSLOPE, CBM_HOUSE_AUTOSLOPE), 177 NIC_END() 178 }; 179 180 static const NIVariable _niv_house[] = { 181 NIV(0x40, "construction state of tile and pseudo-random value"), 182 NIV(0x41, "age of building in years"), 183 NIV(0x42, "town zone"), 184 NIV(0x43, "terrain type"), 185 NIV(0x44, "building counts"), 186 NIV(0x45, "town expansion bits"), 187 NIV(0x46, "current animation frame"), 188 NIV(0x47, "xy coordinate of the building"), 189 NIV(0x60, "other building counts (old house type)"), 190 NIV(0x61, "other building counts (new house type)"), 191 NIV(0x62, "land info of nearby tiles"), 192 NIV(0x63, "current animation frame of nearby house tile"), 193 NIV(0x64, "cargo acceptance history of nearby stations"), 194 NIV(0x65, "distance of nearest house matching a given criterion"), 195 NIV(0x66, "class and ID of nearby house tile"), 196 NIV(0x67, "GRFID of nearby house tile"), 197 NIV_END() 198 }; 199 200 class NIHHouse : public NIHelper { IsInspectable(uint index)201 bool IsInspectable(uint index) const override { return HouseSpec::Get(GetHouseType(index))->grf_prop.grffile != nullptr; } GetParent(uint index)202 uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, GetTownIndex(index)); } GetInstance(uint index)203 const void *GetInstance(uint index)const override { return nullptr; } GetSpec(uint index)204 const void *GetSpec(uint index) const override { return HouseSpec::Get(GetHouseType(index)); } SetStringParameters(uint index)205 void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_TOWN_NAME, GetTownIndex(index), index); } GetGRFID(uint index)206 uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? HouseSpec::Get(GetHouseType(index))->grf_prop.grffile->grfid : 0; } 207 Resolve(uint index,uint var,uint param,bool * avail)208 uint Resolve(uint index, uint var, uint param, bool *avail) const override 209 { 210 HouseResolverObject ro(GetHouseType(index), index, Town::GetByTile(index)); 211 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 212 } 213 }; 214 215 static const NIFeature _nif_house = { 216 nullptr, 217 _nic_house, 218 _niv_house, 219 new NIHHouse(), 220 }; 221 222 223 /*** NewGRF industry tiles ***/ 224 225 #define NICIT(cb_id, bit) NIC(cb_id, IndustryTileSpec, callback_mask, bit) 226 static const NICallback _nic_industrytiles[] = { 227 NICIT(CBID_INDTILE_ANIM_START_STOP, CBM_NO_BIT), 228 NICIT(CBID_INDTILE_ANIM_NEXT_FRAME, CBM_INDT_ANIM_NEXT_FRAME), 229 NICIT(CBID_INDTILE_ANIMATION_SPEED, CBM_INDT_ANIM_SPEED), 230 NICIT(CBID_INDTILE_CARGO_ACCEPTANCE, CBM_INDT_CARGO_ACCEPTANCE), 231 NICIT(CBID_INDTILE_ACCEPT_CARGO, CBM_INDT_ACCEPT_CARGO), 232 NICIT(CBID_INDTILE_SHAPE_CHECK, CBM_INDT_SHAPE_CHECK), 233 NICIT(CBID_INDTILE_DRAW_FOUNDATIONS, CBM_INDT_DRAW_FOUNDATIONS), 234 NICIT(CBID_INDTILE_AUTOSLOPE, CBM_INDT_AUTOSLOPE), 235 NIC_END() 236 }; 237 238 static const NIVariable _niv_industrytiles[] = { 239 NIV(0x40, "construction state of tile"), 240 NIV(0x41, "ground type"), 241 NIV(0x42, "current town zone in nearest town"), 242 NIV(0x43, "relative position"), 243 NIV(0x44, "animation frame"), 244 NIV(0x60, "land info of nearby tiles"), 245 NIV(0x61, "animation stage of nearby tiles"), 246 NIV(0x62, "get industry or airport tile ID at offset"), 247 NIV_END() 248 }; 249 250 class NIHIndustryTile : public NIHelper { IsInspectable(uint index)251 bool IsInspectable(uint index) const override { return GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile != nullptr; } GetParent(uint index)252 uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_INDUSTRIES, GetIndustryIndex(index)); } GetInstance(uint index)253 const void *GetInstance(uint index)const override { return nullptr; } GetSpec(uint index)254 const void *GetSpec(uint index) const override { return GetIndustryTileSpec(GetIndustryGfx(index)); } SetStringParameters(uint index)255 void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_INDUSTRY_NAME, GetIndustryIndex(index), index); } GetGRFID(uint index)256 uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile->grfid : 0; } 257 Resolve(uint index,uint var,uint param,bool * avail)258 uint Resolve(uint index, uint var, uint param, bool *avail) const override 259 { 260 IndustryTileResolverObject ro(GetIndustryGfx(index), index, Industry::GetByTile(index)); 261 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 262 } 263 }; 264 265 static const NIFeature _nif_industrytile = { 266 nullptr, 267 _nic_industrytiles, 268 _niv_industrytiles, 269 new NIHIndustryTile(), 270 }; 271 272 273 /*** NewGRF industries ***/ 274 275 static const NIProperty _nip_industries[] = { 276 NIP(0x25, Industry, produced_cargo[ 0], NIT_CARGO, "produced cargo 0"), 277 NIP(0x25, Industry, produced_cargo[ 1], NIT_CARGO, "produced cargo 1"), 278 NIP(0x25, Industry, produced_cargo[ 2], NIT_CARGO, "produced cargo 2"), 279 NIP(0x25, Industry, produced_cargo[ 3], NIT_CARGO, "produced cargo 3"), 280 NIP(0x25, Industry, produced_cargo[ 4], NIT_CARGO, "produced cargo 4"), 281 NIP(0x25, Industry, produced_cargo[ 5], NIT_CARGO, "produced cargo 5"), 282 NIP(0x25, Industry, produced_cargo[ 6], NIT_CARGO, "produced cargo 6"), 283 NIP(0x25, Industry, produced_cargo[ 7], NIT_CARGO, "produced cargo 7"), 284 NIP(0x25, Industry, produced_cargo[ 8], NIT_CARGO, "produced cargo 8"), 285 NIP(0x25, Industry, produced_cargo[ 9], NIT_CARGO, "produced cargo 9"), 286 NIP(0x25, Industry, produced_cargo[10], NIT_CARGO, "produced cargo 10"), 287 NIP(0x25, Industry, produced_cargo[11], NIT_CARGO, "produced cargo 11"), 288 NIP(0x25, Industry, produced_cargo[12], NIT_CARGO, "produced cargo 12"), 289 NIP(0x25, Industry, produced_cargo[13], NIT_CARGO, "produced cargo 13"), 290 NIP(0x25, Industry, produced_cargo[14], NIT_CARGO, "produced cargo 14"), 291 NIP(0x25, Industry, produced_cargo[15], NIT_CARGO, "produced cargo 15"), 292 NIP(0x26, Industry, accepts_cargo[ 0], NIT_CARGO, "accepted cargo 0"), 293 NIP(0x26, Industry, accepts_cargo[ 1], NIT_CARGO, "accepted cargo 1"), 294 NIP(0x26, Industry, accepts_cargo[ 2], NIT_CARGO, "accepted cargo 2"), 295 NIP(0x26, Industry, accepts_cargo[ 3], NIT_CARGO, "accepted cargo 3"), 296 NIP(0x26, Industry, accepts_cargo[ 4], NIT_CARGO, "accepted cargo 4"), 297 NIP(0x26, Industry, accepts_cargo[ 5], NIT_CARGO, "accepted cargo 5"), 298 NIP(0x26, Industry, accepts_cargo[ 6], NIT_CARGO, "accepted cargo 6"), 299 NIP(0x26, Industry, accepts_cargo[ 7], NIT_CARGO, "accepted cargo 7"), 300 NIP(0x26, Industry, accepts_cargo[ 8], NIT_CARGO, "accepted cargo 8"), 301 NIP(0x26, Industry, accepts_cargo[ 9], NIT_CARGO, "accepted cargo 9"), 302 NIP(0x26, Industry, accepts_cargo[10], NIT_CARGO, "accepted cargo 10"), 303 NIP(0x26, Industry, accepts_cargo[11], NIT_CARGO, "accepted cargo 11"), 304 NIP(0x26, Industry, accepts_cargo[12], NIT_CARGO, "accepted cargo 12"), 305 NIP(0x26, Industry, accepts_cargo[13], NIT_CARGO, "accepted cargo 13"), 306 NIP(0x26, Industry, accepts_cargo[14], NIT_CARGO, "accepted cargo 14"), 307 NIP(0x26, Industry, accepts_cargo[15], NIT_CARGO, "accepted cargo 15"), 308 NIP_END() 309 }; 310 311 #define NICI(cb_id, bit) NIC(cb_id, IndustrySpec, callback_mask, bit) 312 static const NICallback _nic_industries[] = { 313 NICI(CBID_INDUSTRY_PROBABILITY, CBM_IND_PROBABILITY), 314 NICI(CBID_INDUSTRY_LOCATION, CBM_IND_LOCATION), 315 NICI(CBID_INDUSTRY_PRODUCTION_CHANGE, CBM_IND_PRODUCTION_CHANGE), 316 NICI(CBID_INDUSTRY_MONTHLYPROD_CHANGE, CBM_IND_MONTHLYPROD_CHANGE), 317 NICI(CBID_INDUSTRY_CARGO_SUFFIX, CBM_IND_CARGO_SUFFIX), 318 NICI(CBID_INDUSTRY_FUND_MORE_TEXT, CBM_IND_FUND_MORE_TEXT), 319 NICI(CBID_INDUSTRY_WINDOW_MORE_TEXT, CBM_IND_WINDOW_MORE_TEXT), 320 NICI(CBID_INDUSTRY_SPECIAL_EFFECT, CBM_IND_SPECIAL_EFFECT), 321 NICI(CBID_INDUSTRY_REFUSE_CARGO, CBM_IND_REFUSE_CARGO), 322 NICI(CBID_INDUSTRY_DECIDE_COLOUR, CBM_IND_DECIDE_COLOUR), 323 NICI(CBID_INDUSTRY_INPUT_CARGO_TYPES, CBM_IND_INPUT_CARGO_TYPES), 324 NICI(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, CBM_IND_OUTPUT_CARGO_TYPES), 325 NICI(CBID_INDUSTRY_PROD_CHANGE_BUILD, CBM_IND_PROD_CHANGE_BUILD), 326 NIC_END() 327 }; 328 329 static const NIVariable _niv_industries[] = { 330 NIV(0x40, "waiting cargo 0"), 331 NIV(0x41, "waiting cargo 1"), 332 NIV(0x42, "waiting cargo 2"), 333 NIV(0x43, "distance to closest dry/land tile"), 334 NIV(0x44, "layout number"), 335 NIV(0x45, "player info"), 336 NIV(0x46, "industry construction date"), 337 NIV(0x60, "get industry tile ID at offset"), 338 NIV(0x61, "get random tile bits at offset"), 339 NIV(0x62, "land info of nearby tiles"), 340 NIV(0x63, "animation stage of nearby tiles"), 341 NIV(0x64, "distance on nearest industry with given type"), 342 NIV(0x65, "get town zone and Manhattan distance of closest town"), 343 NIV(0x66, "get square of Euclidean distance of closes town"), 344 NIV(0x67, "count of industry and distance of closest instance"), 345 NIV(0x68, "count of industry and distance of closest instance with layout filter"), 346 NIV(0x69, "produced cargo waiting"), 347 NIV(0x6A, "cargo produced this month"), 348 NIV(0x6B, "cargo transported this month"), 349 NIV(0x6C, "cargo produced last month"), 350 NIV(0x6D, "cargo transported last month"), 351 NIV(0x6E, "date since cargo was delivered"), 352 NIV(0x6F, "waiting input cargo"), 353 NIV(0x70, "production rate"), 354 NIV(0x71, "percentage of cargo transported last month"), 355 NIV_END() 356 }; 357 358 class NIHIndustry : public NIHelper { IsInspectable(uint index)359 bool IsInspectable(uint index) const override { return GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile != nullptr; } GetParent(uint index)360 uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Industry::Get(index)->town->index); } GetInstance(uint index)361 const void *GetInstance(uint index)const override { return Industry::Get(index); } GetSpec(uint index)362 const void *GetSpec(uint index) const override { return GetIndustrySpec(Industry::Get(index)->type); } SetStringParameters(uint index)363 void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_INDUSTRY_NAME, index); } GetGRFID(uint index)364 uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile->grfid : 0; } 365 Resolve(uint index,uint var,uint param,bool * avail)366 uint Resolve(uint index, uint var, uint param, bool *avail) const override 367 { 368 Industry *i = Industry::Get(index); 369 IndustriesResolverObject ro(i->location.tile, i, i->type); 370 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 371 } 372 GetPSASize(uint index,uint32 grfid)373 uint GetPSASize(uint index, uint32 grfid) const override { return cpp_lengthof(PersistentStorage, storage); } 374 GetPSAFirstPosition(uint index,uint32 grfid)375 const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const override 376 { 377 const Industry *i = (const Industry *)this->GetInstance(index); 378 if (i->psa == nullptr) return nullptr; 379 return (int32 *)(&i->psa->storage); 380 } 381 }; 382 383 static const NIFeature _nif_industry = { 384 _nip_industries, 385 _nic_industries, 386 _niv_industries, 387 new NIHIndustry(), 388 }; 389 390 391 /*** NewGRF objects ***/ 392 393 #define NICO(cb_id, bit) NIC(cb_id, ObjectSpec, callback_mask, bit) 394 static const NICallback _nic_objects[] = { 395 NICO(CBID_OBJECT_LAND_SLOPE_CHECK, CBM_OBJ_SLOPE_CHECK), 396 NICO(CBID_OBJECT_ANIMATION_NEXT_FRAME, CBM_OBJ_ANIMATION_NEXT_FRAME), 397 NICO(CBID_OBJECT_ANIMATION_START_STOP, CBM_NO_BIT), 398 NICO(CBID_OBJECT_ANIMATION_SPEED, CBM_OBJ_ANIMATION_SPEED), 399 NICO(CBID_OBJECT_COLOUR, CBM_OBJ_COLOUR), 400 NICO(CBID_OBJECT_FUND_MORE_TEXT, CBM_OBJ_FUND_MORE_TEXT), 401 NICO(CBID_OBJECT_AUTOSLOPE, CBM_OBJ_AUTOSLOPE), 402 NIC_END() 403 }; 404 405 static const NIVariable _niv_objects[] = { 406 NIV(0x40, "relative position"), 407 NIV(0x41, "tile information"), 408 NIV(0x42, "construction date"), 409 NIV(0x43, "animation counter"), 410 NIV(0x44, "object founder"), 411 NIV(0x45, "get town zone and Manhattan distance of closest town"), 412 NIV(0x46, "get square of Euclidean distance of closes town"), 413 NIV(0x47, "colour"), 414 NIV(0x48, "view"), 415 NIV(0x60, "get object ID at offset"), 416 NIV(0x61, "get random tile bits at offset"), 417 NIV(0x62, "land info of nearby tiles"), 418 NIV(0x63, "animation stage of nearby tiles"), 419 NIV(0x64, "distance on nearest object with given type"), 420 NIV_END() 421 }; 422 423 class NIHObject : public NIHelper { IsInspectable(uint index)424 bool IsInspectable(uint index) const override { return ObjectSpec::GetByTile(index)->grf_prop.grffile != nullptr; } GetParent(uint index)425 uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Object::GetByTile(index)->town->index); } GetInstance(uint index)426 const void *GetInstance(uint index)const override { return Object::GetByTile(index); } GetSpec(uint index)427 const void *GetSpec(uint index) const override { return ObjectSpec::GetByTile(index); } SetStringParameters(uint index)428 void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT, INVALID_STRING_ID, index); } GetGRFID(uint index)429 uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? ObjectSpec::GetByTile(index)->grf_prop.grffile->grfid : 0; } 430 Resolve(uint index,uint var,uint param,bool * avail)431 uint Resolve(uint index, uint var, uint param, bool *avail) const override 432 { 433 ObjectResolverObject ro(ObjectSpec::GetByTile(index), Object::GetByTile(index), index); 434 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 435 } 436 }; 437 438 static const NIFeature _nif_object = { 439 nullptr, 440 _nic_objects, 441 _niv_objects, 442 new NIHObject(), 443 }; 444 445 446 /*** NewGRF rail types ***/ 447 448 static const NIVariable _niv_railtypes[] = { 449 NIV(0x40, "terrain type"), 450 NIV(0x41, "enhanced tunnels"), 451 NIV(0x42, "level crossing status"), 452 NIV(0x43, "construction date"), 453 NIV(0x44, "town zone"), 454 NIV_END() 455 }; 456 457 class NIHRailType : public NIHelper { IsInspectable(uint index)458 bool IsInspectable(uint index) const override { return true; } GetParent(uint index)459 uint GetParent(uint index) const override { return UINT32_MAX; } GetInstance(uint index)460 const void *GetInstance(uint index)const override { return nullptr; } GetSpec(uint index)461 const void *GetSpec(uint index) const override { return nullptr; } SetStringParameters(uint index)462 void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); } GetGRFID(uint index)463 uint32 GetGRFID(uint index) const override { return 0; } 464 Resolve(uint index,uint var,uint param,bool * avail)465 uint Resolve(uint index, uint var, uint param, bool *avail) const override 466 { 467 /* There is no unique GRFFile for the tile. Multiple GRFs can define different parts of the railtype. 468 * However, currently the NewGRF Debug GUI does not display variables depending on the GRF (like 0x7F) anyway. */ 469 RailTypeResolverObject ro(nullptr, index, TCX_NORMAL, RTSG_END); 470 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 471 } 472 }; 473 474 static const NIFeature _nif_railtype = { 475 nullptr, 476 nullptr, 477 _niv_railtypes, 478 new NIHRailType(), 479 }; 480 481 482 /*** NewGRF airport tiles ***/ 483 484 #define NICAT(cb_id, bit) NIC(cb_id, AirportTileSpec, callback_mask, bit) 485 static const NICallback _nic_airporttiles[] = { 486 NICAT(CBID_AIRPTILE_DRAW_FOUNDATIONS, CBM_AIRT_DRAW_FOUNDATIONS), 487 NICAT(CBID_AIRPTILE_ANIM_START_STOP, CBM_NO_BIT), 488 NICAT(CBID_AIRPTILE_ANIM_NEXT_FRAME, CBM_AIRT_ANIM_NEXT_FRAME), 489 NICAT(CBID_AIRPTILE_ANIMATION_SPEED, CBM_AIRT_ANIM_SPEED), 490 NIC_END() 491 }; 492 493 class NIHAirportTile : public NIHelper { IsInspectable(uint index)494 bool IsInspectable(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile != nullptr; } GetParent(uint index)495 uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); } GetInstance(uint index)496 const void *GetInstance(uint index)const override { return nullptr; } GetSpec(uint index)497 const void *GetSpec(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(index)); } SetStringParameters(uint index)498 void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); } GetGRFID(uint index)499 uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile->grfid : 0; } 500 Resolve(uint index,uint var,uint param,bool * avail)501 uint Resolve(uint index, uint var, uint param, bool *avail) const override 502 { 503 AirportTileResolverObject ro(AirportTileSpec::GetByTile(index), index, Station::GetByTile(index)); 504 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 505 } 506 }; 507 508 static const NIFeature _nif_airporttile = { 509 nullptr, 510 _nic_airporttiles, 511 _niv_industrytiles, // Yes, they share this (at least now) 512 new NIHAirportTile(), 513 }; 514 515 516 /*** NewGRF towns ***/ 517 518 static const NIVariable _niv_towns[] = { 519 NIV(0x40, "larger town effect on this town"), 520 NIV(0x41, "town index"), 521 NIV(0x82, "population"), 522 NIV(0x94, "zone radius 0"), 523 NIV(0x96, "zone radius 1"), 524 NIV(0x98, "zone radius 2"), 525 NIV(0x9A, "zone radius 3"), 526 NIV(0x9C, "zone radius 4"), 527 NIV(0xB6, "number of buildings"), 528 NIV_END() 529 }; 530 531 class NIHTown : public NIHelper { IsInspectable(uint index)532 bool IsInspectable(uint index) const override { return Town::IsValidID(index); } GetParent(uint index)533 uint GetParent(uint index) const override { return UINT32_MAX; } GetInstance(uint index)534 const void *GetInstance(uint index)const override { return Town::Get(index); } GetSpec(uint index)535 const void *GetSpec(uint index) const override { return nullptr; } SetStringParameters(uint index)536 void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_TOWN_NAME, index); } GetGRFID(uint index)537 uint32 GetGRFID(uint index) const override { return 0; } PSAWithParameter()538 bool PSAWithParameter() const override { return true; } GetPSASize(uint index,uint32 grfid)539 uint GetPSASize(uint index, uint32 grfid) const override { return cpp_lengthof(PersistentStorage, storage); } 540 Resolve(uint index,uint var,uint param,bool * avail)541 uint Resolve(uint index, uint var, uint param, bool *avail) const override 542 { 543 TownResolverObject ro(nullptr, Town::Get(index), true); 544 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 545 } 546 GetPSAFirstPosition(uint index,uint32 grfid)547 const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const override 548 { 549 Town *t = Town::Get(index); 550 551 std::list<PersistentStorage *>::iterator iter; 552 for (iter = t->psa_list.begin(); iter != t->psa_list.end(); iter++) { 553 if ((*iter)->grfid == grfid) return (int32 *)(&(*iter)->storage[0]); 554 } 555 556 return nullptr; 557 } 558 }; 559 560 static const NIFeature _nif_town = { 561 nullptr, 562 nullptr, 563 _niv_towns, 564 new NIHTown(), 565 }; 566 567 /*** NewGRF road types ***/ 568 569 static const NIVariable _niv_roadtypes[] = { 570 NIV(0x40, "terrain type"), 571 NIV(0x41, "enhanced tunnels"), 572 NIV(0x42, "level crossing status"), 573 NIV(0x43, "construction date"), 574 NIV(0x44, "town zone"), 575 NIV_END() 576 }; 577 578 class NIHRoadType : public NIHelper { IsInspectable(uint index)579 bool IsInspectable(uint index) const override { return true; } GetParent(uint index)580 uint GetParent(uint index) const override { return UINT32_MAX; } GetInstance(uint index)581 const void *GetInstance(uint index) const override { return nullptr; } GetSpec(uint index)582 const void *GetSpec(uint index) const override { return nullptr; } SetStringParameters(uint index)583 void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); } GetGRFID(uint index)584 uint32 GetGRFID(uint index) const override { return 0; } 585 Resolve(uint index,uint var,uint param,bool * avail)586 uint Resolve(uint index, uint var, uint param, bool *avail) const override 587 { 588 /* There is no unique GRFFile for the tile. Multiple GRFs can define different parts of the railtype. 589 * However, currently the NewGRF Debug GUI does not display variables depending on the GRF (like 0x7F) anyway. */ 590 RoadTypeResolverObject ro(nullptr, index, TCX_NORMAL, ROTSG_END); 591 return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); 592 } 593 }; 594 595 static const NIFeature _nif_roadtype = { 596 nullptr, 597 nullptr, 598 _niv_roadtypes, 599 new NIHRoadType(), 600 }; 601 602 static const NIFeature _nif_tramtype = { 603 nullptr, 604 nullptr, 605 _niv_roadtypes, 606 new NIHRoadType(), 607 }; 608 609 /** Table with all NIFeatures. */ 610 static const NIFeature * const _nifeatures[] = { 611 &_nif_vehicle, // GSF_TRAINS 612 &_nif_vehicle, // GSF_ROADVEHICLES 613 &_nif_vehicle, // GSF_SHIPS 614 &_nif_vehicle, // GSF_AIRCRAFT 615 &_nif_station, // GSF_STATIONS 616 nullptr, // GSF_CANALS (no callbacks/action2 implemented) 617 nullptr, // GSF_BRIDGES (no callbacks/action2) 618 &_nif_house, // GSF_HOUSES 619 nullptr, // GSF_GLOBALVAR (has no "physical" objects) 620 &_nif_industrytile, // GSF_INDUSTRYTILES 621 &_nif_industry, // GSF_INDUSTRIES 622 nullptr, // GSF_CARGOES (has no "physical" objects) 623 nullptr, // GSF_SOUNDFX (has no "physical" objects) 624 nullptr, // GSF_AIRPORTS (feature not implemented) 625 nullptr, // GSF_SIGNALS (feature not implemented) 626 &_nif_object, // GSF_OBJECTS 627 &_nif_railtype, // GSF_RAILTYPES 628 &_nif_airporttile, // GSF_AIRPORTTILES 629 &_nif_roadtype, // GSF_ROADTYPES 630 &_nif_tramtype, // GSF_TRAMTYPES 631 &_nif_town, // GSF_FAKE_TOWNS 632 }; 633 static_assert(lengthof(_nifeatures) == GSF_FAKE_END); 634