OpenTTD Source  1.10.0-RC1
newgrf_station.cpp
Go to the documentation of this file.
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 
10 #include "stdafx.h"
11 #include "debug.h"
12 #include "station_base.h"
13 #include "waypoint_base.h"
14 #include "roadstop_base.h"
15 #include "newgrf_cargo.h"
16 #include "newgrf_station.h"
17 #include "newgrf_spritegroup.h"
18 #include "newgrf_sound.h"
19 #include "newgrf_railtype.h"
20 #include "town.h"
21 #include "newgrf_town.h"
22 #include "company_func.h"
23 #include "tunnelbridge_map.h"
24 #include "newgrf_animation_base.h"
25 #include "newgrf_class_func.h"
26 
27 #include "safeguards.h"
28 
29 
30 template <typename Tspec, typename Tid, Tid Tmax>
32 {
33  /* Set up initial data */
34  classes[0].global_id = 'DFLT';
35  classes[0].name = STR_STATION_CLASS_DFLT;
36  classes[0].Insert(nullptr);
37 
38  classes[1].global_id = 'WAYP';
39  classes[1].name = STR_STATION_CLASS_WAYP;
40  classes[1].Insert(nullptr);
41 }
42 
43 template <typename Tspec, typename Tid, Tid Tmax>
45 {
46  return true;
47 }
48 
50 
51 static const uint NUM_STATIONSSPECS_PER_STATION = 255;
52 
53 enum TriggerArea {
54  TA_TILE,
55  TA_PLATFORM,
56  TA_WHOLE,
57 };
58 
59 struct ETileArea : TileArea {
60  ETileArea(const BaseStation *st, TileIndex tile, TriggerArea ta)
61  {
62  switch (ta) {
63  default: NOT_REACHED();
64 
65  case TA_TILE:
66  this->tile = tile;
67  this->w = 1;
68  this->h = 1;
69  break;
70 
71  case TA_PLATFORM: {
72  TileIndex start, end;
73  Axis axis = GetRailStationAxis(tile);
75 
76  for (end = tile; IsRailStationTile(end + delta) && IsCompatibleTrainStationTile(end + delta, tile); end += delta) { /* Nothing */ }
77  for (start = tile; IsRailStationTile(start - delta) && IsCompatibleTrainStationTile(start - delta, tile); start -= delta) { /* Nothing */ }
78 
79  this->tile = start;
80  this->w = TileX(end) - TileX(start) + 1;
81  this->h = TileY(end) - TileY(start) + 1;
82  break;
83  }
84 
85  case TA_WHOLE:
86  st->GetTileArea(this, Station::IsExpected(st) ? STATION_RAIL : STATION_WAYPOINT);
87  break;
88  }
89  }
90 };
91 
92 
105 uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, int y, bool centred)
106 {
107  uint32 retval = 0;
108 
109  if (axis == AXIS_X) {
110  Swap(platforms, length);
111  Swap(x, y);
112  }
113 
114  if (centred) {
115  x -= platforms / 2;
116  y -= length / 2;
117  x = Clamp(x, -8, 7);
118  y = Clamp(y, -8, 7);
119  SB(retval, 0, 4, y & 0xF);
120  SB(retval, 4, 4, x & 0xF);
121  } else {
122  SB(retval, 0, 4, min(15, y));
123  SB(retval, 4, 4, min(15, length - y - 1));
124  SB(retval, 8, 4, min(15, x));
125  SB(retval, 12, 4, min(15, platforms - x - 1));
126  }
127  SB(retval, 16, 4, min(15, length));
128  SB(retval, 20, 4, min(15, platforms));
129  SB(retval, 24, 4, tile);
130 
131  return retval;
132 }
133 
134 
143 static TileIndex FindRailStationEnd(TileIndex tile, TileIndexDiff delta, bool check_type, bool check_axis)
144 {
145  byte orig_type = 0;
146  Axis orig_axis = AXIS_X;
147  StationID sid = GetStationIndex(tile);
148 
149  if (check_type) orig_type = GetCustomStationSpecIndex(tile);
150  if (check_axis) orig_axis = GetRailStationAxis(tile);
151 
152  for (;;) {
153  TileIndex new_tile = TILE_ADD(tile, delta);
154 
155  if (!IsTileType(new_tile, MP_STATION) || GetStationIndex(new_tile) != sid) break;
156  if (!HasStationRail(new_tile)) break;
157  if (check_type && GetCustomStationSpecIndex(new_tile) != orig_type) break;
158  if (check_axis && GetRailStationAxis(new_tile) != orig_axis) break;
159 
160  tile = new_tile;
161  }
162  return tile;
163 }
164 
165 
166 static uint32 GetPlatformInfoHelper(TileIndex tile, bool check_type, bool check_axis, bool centred)
167 {
168  int tx = TileX(tile);
169  int ty = TileY(tile);
170  int sx = TileX(FindRailStationEnd(tile, TileDiffXY(-1, 0), check_type, check_axis));
171  int sy = TileY(FindRailStationEnd(tile, TileDiffXY( 0, -1), check_type, check_axis));
172  int ex = TileX(FindRailStationEnd(tile, TileDiffXY( 1, 0), check_type, check_axis)) + 1;
173  int ey = TileY(FindRailStationEnd(tile, TileDiffXY( 0, 1), check_type, check_axis)) + 1;
174 
175  tx -= sx; ex -= sx;
176  ty -= sy; ey -= sy;
177 
178  return GetPlatformInfo(GetRailStationAxis(tile), GetStationGfx(tile), ex, ey, tx, ty, centred);
179 }
180 
181 
182 static uint32 GetRailContinuationInfo(TileIndex tile)
183 {
184  /* Tile offsets and exit dirs for X axis */
185  static const Direction x_dir[8] = { DIR_SW, DIR_NE, DIR_SE, DIR_NW, DIR_S, DIR_E, DIR_W, DIR_N };
186  static const DiagDirection x_exits[8] = { DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SW, DIAGDIR_NE };
187 
188  /* Tile offsets and exit dirs for Y axis */
189  static const Direction y_dir[8] = { DIR_SE, DIR_NW, DIR_SW, DIR_NE, DIR_S, DIR_W, DIR_E, DIR_N };
190  static const DiagDirection y_exits[8] = { DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SE, DIAGDIR_NW };
191 
192  Axis axis = GetRailStationAxis(tile);
193 
194  /* Choose appropriate lookup table to use */
195  const Direction *dir = axis == AXIS_X ? x_dir : y_dir;
196  const DiagDirection *diagdir = axis == AXIS_X ? x_exits : y_exits;
197 
198  uint32 res = 0;
199  uint i;
200 
201  for (i = 0; i < lengthof(x_dir); i++, dir++, diagdir++) {
202  TileIndex neighbour_tile = tile + TileOffsByDir(*dir);
203  TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(neighbour_tile, TRANSPORT_RAIL, 0));
204  if (trackbits != TRACK_BIT_NONE) {
205  /* If there is any track on the tile, set the bit in the second byte */
206  SetBit(res, i + 8);
207 
208  /* With tunnels and bridges the tile has tracks, but they are not necessarily connected
209  * with the next tile because the ramp is not going in the right direction. */
210  if (IsTileType(neighbour_tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(neighbour_tile) != *diagdir) {
211  continue;
212  }
213 
214  /* If any track reaches our exit direction, set the bit in the lower byte */
215  if (trackbits & DiagdirReachesTracks(*diagdir)) SetBit(res, i);
216  }
217  }
218 
219  return res;
220 }
221 
222 
223 /* Station Resolver Functions */
224 /* virtual */ uint32 StationScopeResolver::GetRandomBits() const
225 {
226  return (this->st == nullptr ? 0 : this->st->random_bits) | (this->tile == INVALID_TILE ? 0 : GetStationTileRandomBits(this->tile) << 16);
227 }
228 
229 
230 /* virtual */ uint32 StationScopeResolver::GetTriggers() const
231 {
232  return this->st == nullptr ? 0 : this->st->waiting_triggers;
233 }
234 
235 
241 static struct {
242  uint32 v40;
243  uint32 v41;
244  uint32 v45;
245  uint32 v46;
246  uint32 v47;
247  uint32 v49;
248  uint8 valid;
249 } _svc;
250 
257 {
258  if (this->town_scope == nullptr) {
259  Town *t = nullptr;
260  if (this->station_scope.st != nullptr) {
261  t = this->station_scope.st->town;
262  } else if (this->station_scope.tile != INVALID_TILE) {
263  t = ClosestTownFromTile(this->station_scope.tile, UINT_MAX);
264  }
265  if (t == nullptr) return nullptr;
266  this->town_scope = new TownScopeResolver(*this, t, this->station_scope.st == nullptr);
267  }
268  return this->town_scope;
269 }
270 
271 /* virtual */ uint32 StationScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
272 {
273  if (this->st == nullptr) {
274  /* Station does not exist, so we're in a purchase list or the land slope check callback. */
275  switch (variable) {
276  case 0x40:
277  case 0x41:
278  case 0x46:
279  case 0x47:
280  case 0x49: return 0x2110000; // Platforms, tracks & position
281  case 0x42: return 0; // Rail type (XXX Get current type from GUI?)
282  case 0x43: return GetCompanyInfo(_current_company); // Station owner
283  case 0x44: return 2; // PBS status
284  case 0x67: // Land info of nearby tile
285  if (this->axis != INVALID_AXIS && this->tile != INVALID_TILE) {
286  TileIndex tile = this->tile;
287  if (parameter != 0) tile = GetNearbyTile(parameter, tile, true, this->axis); // only perform if it is required
288 
289  Slope tileh = GetTileSlope(tile);
290  bool swap = (this->axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E));
291 
292  return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8) ^ (swap ? SLOPE_EW : 0);
293  }
294  break;
295 
296  case 0xFA: return Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Build date, clamped to a 16 bit value
297  }
298 
299  *available = false;
300  return UINT_MAX;
301  }
302 
303  switch (variable) {
304  /* Calculated station variables */
305  case 0x40:
306  if (!HasBit(_svc.valid, 0)) { _svc.v40 = GetPlatformInfoHelper(this->tile, false, false, false); SetBit(_svc.valid, 0); }
307  return _svc.v40;
308 
309  case 0x41:
310  if (!HasBit(_svc.valid, 1)) { _svc.v41 = GetPlatformInfoHelper(this->tile, true, false, false); SetBit(_svc.valid, 1); }
311  return _svc.v41;
312 
313  case 0x42: return GetTerrainType(this->tile) | (GetReverseRailTypeTranslation(GetRailType(this->tile), this->statspec->grf_prop.grffile) << 8);
314  case 0x43: return GetCompanyInfo(this->st->owner); // Station owner
315  case 0x44: return HasStationReservation(this->tile) ? 7 : 4; // PBS status
316  case 0x45:
317  if (!HasBit(_svc.valid, 2)) { _svc.v45 = GetRailContinuationInfo(this->tile); SetBit(_svc.valid, 2); }
318  return _svc.v45;
319 
320  case 0x46:
321  if (!HasBit(_svc.valid, 3)) { _svc.v46 = GetPlatformInfoHelper(this->tile, false, false, true); SetBit(_svc.valid, 3); }
322  return _svc.v46;
323 
324  case 0x47:
325  if (!HasBit(_svc.valid, 4)) { _svc.v47 = GetPlatformInfoHelper(this->tile, true, false, true); SetBit(_svc.valid, 4); }
326  return _svc.v47;
327 
328  case 0x49:
329  if (!HasBit(_svc.valid, 5)) { _svc.v49 = GetPlatformInfoHelper(this->tile, false, true, false); SetBit(_svc.valid, 5); }
330  return _svc.v49;
331 
332  case 0x4A: // Animation frame of tile
333  return GetAnimationFrame(this->tile);
334 
335  /* Variables which use the parameter */
336  /* Variables 0x60 to 0x65 and 0x69 are handled separately below */
337  case 0x66: { // Animation frame of nearby tile
338  TileIndex tile = this->tile;
339  if (parameter != 0) tile = GetNearbyTile(parameter, tile);
340  return this->st->TileBelongsToRailStation(tile) ? GetAnimationFrame(tile) : UINT_MAX;
341  }
342 
343  case 0x67: { // Land info of nearby tile
344  Axis axis = GetRailStationAxis(this->tile);
345  TileIndex tile = this->tile;
346  if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required
347 
348  Slope tileh = GetTileSlope(tile);
349  bool swap = (axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E));
350 
351  return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8) ^ (swap ? SLOPE_EW : 0);
352  }
353 
354  case 0x68: { // Station info of nearby tiles
355  TileIndex nearby_tile = GetNearbyTile(parameter, this->tile);
356 
357  if (!HasStationTileRail(nearby_tile)) return 0xFFFFFFFF;
358 
359  uint32 grfid = this->st->speclist[GetCustomStationSpecIndex(this->tile)].grfid;
360  bool perpendicular = GetRailStationAxis(this->tile) != GetRailStationAxis(nearby_tile);
361  bool same_station = this->st->TileBelongsToRailStation(nearby_tile);
362  uint32 res = GB(GetStationGfx(nearby_tile), 1, 2) << 12 | !!perpendicular << 11 | !!same_station << 10;
363 
364  if (IsCustomStationSpecIndex(nearby_tile)) {
365  const StationSpecList ssl = BaseStation::GetByTile(nearby_tile)->speclist[GetCustomStationSpecIndex(nearby_tile)];
366  res |= 1 << (ssl.grfid != grfid ? 9 : 8) | ssl.localidx;
367  }
368  return res;
369  }
370 
371  case 0x6A: { // GRFID of nearby station tiles
372  TileIndex nearby_tile = GetNearbyTile(parameter, this->tile);
373 
374  if (!HasStationTileRail(nearby_tile)) return 0xFFFFFFFF;
375  if (!IsCustomStationSpecIndex(nearby_tile)) return 0;
376 
377  const StationSpecList ssl = BaseStation::GetByTile(nearby_tile)->speclist[GetCustomStationSpecIndex(nearby_tile)];
378  return ssl.grfid;
379  }
380 
381  /* General station variables */
382  case 0x82: return 50;
383  case 0x84: return this->st->string_id;
384  case 0x86: return 0;
385  case 0xF0: return this->st->facilities;
386  case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
387  }
388 
389  return this->st->GetNewGRFVariable(this->ro, variable, parameter, available);
390 }
391 
392 uint32 Station::GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const
393 {
394  switch (variable) {
395  case 0x48: { // Accepted cargo types
396  CargoID cargo_type;
397  uint32 value = 0;
398 
399  for (cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
400  if (HasBit(this->goods[cargo_type].status, GoodsEntry::GES_ACCEPTANCE)) SetBit(value, cargo_type);
401  }
402  return value;
403  }
404 
405  case 0x8A: return this->had_vehicle_of_type;
406  case 0xF1: return (this->airport.tile != INVALID_TILE) ? this->airport.GetSpec()->ttd_airport_type : ATP_TTDP_LARGE;
407  case 0xF2: return (this->truck_stops != nullptr) ? this->truck_stops->status : 0;
408  case 0xF3: return (this->bus_stops != nullptr) ? this->bus_stops->status : 0;
409  case 0xF6: return this->airport.flags;
410  case 0xF7: return GB(this->airport.flags, 8, 8);
411  }
412 
413  /* Handle cargo variables with parameter, 0x60 to 0x65 and 0x69 */
414  if ((variable >= 0x60 && variable <= 0x65) || variable == 0x69) {
415  CargoID c = GetCargoTranslation(parameter, object.grffile);
416 
417  if (c == CT_INVALID) {
418  switch (variable) {
419  case 0x62: return 0xFFFFFFFF;
420  case 0x64: return 0xFF00;
421  default: return 0;
422  }
423  }
424  const GoodsEntry *ge = &this->goods[c];
425 
426  switch (variable) {
427  case 0x60: return min(ge->cargo.TotalCount(), 4095);
428  case 0x61: return ge->HasVehicleEverTriedLoading() ? ge->time_since_pickup : 0;
429  case 0x62: return ge->HasRating() ? ge->rating : 0xFFFFFFFF;
430  case 0x63: return ge->cargo.DaysInTransit();
431  case 0x64: return ge->HasVehicleEverTriedLoading() ? ge->last_speed | (ge->last_age << 8) : 0xFF00;
432  case 0x65: return GB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1) << 3;
433  case 0x69: {
434  assert_compile((int)GoodsEntry::GES_EVER_ACCEPTED + 1 == (int)GoodsEntry::GES_LAST_MONTH);
435  assert_compile((int)GoodsEntry::GES_EVER_ACCEPTED + 2 == (int)GoodsEntry::GES_CURRENT_MONTH);
436  assert_compile((int)GoodsEntry::GES_EVER_ACCEPTED + 3 == (int)GoodsEntry::GES_ACCEPTED_BIGTICK);
437  return GB(ge->status, GoodsEntry::GES_EVER_ACCEPTED, 4);
438  }
439  }
440  }
441 
442  /* Handle cargo variables (deprecated) */
443  if (variable >= 0x8C && variable <= 0xEC) {
444  const GoodsEntry *g = &this->goods[GB(variable - 0x8C, 3, 4)];
445  switch (GB(variable - 0x8C, 0, 3)) {
446  case 0: return g->cargo.TotalCount();
447  case 1: return GB(min(g->cargo.TotalCount(), 4095), 0, 4) | (GB(g->status, GoodsEntry::GES_ACCEPTANCE, 1) << 7);
448  case 2: return g->time_since_pickup;
449  case 3: return g->rating;
450  case 4: return g->cargo.Source();
451  case 5: return g->cargo.DaysInTransit();
452  case 6: return g->last_speed;
453  case 7: return g->last_age;
454  }
455  }
456 
457  DEBUG(grf, 1, "Unhandled station variable 0x%X", variable);
458 
459  *available = false;
460  return UINT_MAX;
461 }
462 
463 uint32 Waypoint::GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const
464 {
465  switch (variable) {
466  case 0x48: return 0; // Accepted cargo types
467  case 0x8A: return HVOT_WAYPOINT;
468  case 0xF1: return 0; // airport type
469  case 0xF2: return 0; // truck stop status
470  case 0xF3: return 0; // bus stop status
471  case 0xF6: return 0; // airport flags
472  case 0xF7: return 0; // airport flags cont.
473  }
474 
475  /* Handle cargo variables with parameter, 0x60 to 0x65 */
476  if (variable >= 0x60 && variable <= 0x65) {
477  return 0;
478  }
479 
480  /* Handle cargo variables (deprecated) */
481  if (variable >= 0x8C && variable <= 0xEC) {
482  switch (GB(variable - 0x8C, 0, 3)) {
483  case 3: return INITIAL_STATION_RATING;
484  case 4: return INVALID_STATION;
485  default: return 0;
486  }
487  }
488 
489  DEBUG(grf, 1, "Unhandled station variable 0x%X", variable);
490 
491  *available = false;
492  return UINT_MAX;
493 }
494 
495 /* virtual */ const SpriteGroup *StationResolverObject::ResolveReal(const RealSpriteGroup *group) const
496 {
497  if (this->station_scope.st == nullptr || this->station_scope.statspec->cls_id == STAT_CLASS_WAYP) {
498  return group->loading[0];
499  }
500 
501  uint cargo = 0;
502  const Station *st = Station::From(this->station_scope.st);
503 
504  switch (this->station_scope.cargo_type) {
505  case CT_INVALID:
506  case CT_DEFAULT_NA:
507  case CT_PURCHASE:
508  cargo = 0;
509  break;
510 
511  case CT_DEFAULT:
512  for (CargoID cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
513  cargo += st->goods[cargo_type].cargo.TotalCount();
514  }
515  break;
516 
517  default:
518  cargo = st->goods[this->station_scope.cargo_type].cargo.TotalCount();
519  break;
520  }
521 
522  if (HasBit(this->station_scope.statspec->flags, SSF_DIV_BY_STATION_SIZE)) cargo /= (st->train_station.w + st->train_station.h);
523  cargo = min(0xfff, cargo);
524 
525  if (cargo > this->station_scope.statspec->cargo_threshold) {
526  if (group->num_loading > 0) {
527  uint set = ((cargo - this->station_scope.statspec->cargo_threshold) * group->num_loading) / (4096 - this->station_scope.statspec->cargo_threshold);
528  return group->loading[set];
529  }
530  } else {
531  if (group->num_loaded > 0) {
532  uint set = (cargo * group->num_loaded) / (this->station_scope.statspec->cargo_threshold + 1);
533  return group->loaded[set];
534  }
535  }
536 
537  return group->loading[0];
538 }
539 
541 {
542  return GSF_STATIONS;
543 }
544 
546 {
547  return this->station_scope.statspec->grf_prop.local_id;
548 }
549 
560  CallbackID callback, uint32 callback_param1, uint32 callback_param2)
561  : ResolverObject(statspec->grf_prop.grffile, callback, callback_param1, callback_param2),
562  station_scope(*this, statspec, st, tile), town_scope(nullptr)
563 {
564  /* Invalidate all cached vars */
565  _svc.valid = 0;
566 
567  CargoID ctype = CT_DEFAULT_NA;
568 
569  if (this->station_scope.st == nullptr) {
570  /* No station, so we are in a purchase list */
571  ctype = CT_PURCHASE;
572  } else if (Station::IsExpected(this->station_scope.st)) {
573  const Station *st = Station::From(this->station_scope.st);
574  /* Pick the first cargo that we have waiting */
575  const CargoSpec *cs;
576  FOR_ALL_CARGOSPECS(cs) {
577  if (this->station_scope.statspec->grf_prop.spritegroup[cs->Index()] != nullptr &&
578  st->goods[cs->Index()].cargo.TotalCount() > 0) {
579  ctype = cs->Index();
580  break;
581  }
582  }
583  }
584 
585  if (this->station_scope.statspec->grf_prop.spritegroup[ctype] == nullptr) {
586  ctype = CT_DEFAULT;
587  }
588 
589  /* Remember the cargo type we've picked */
590  this->station_scope.cargo_type = ctype;
592 }
593 
594 StationResolverObject::~StationResolverObject()
595 {
596  delete this->town_scope;
597 }
598 
607 SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint32 var10)
608 {
609  StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, var10);
610  const SpriteGroup *group = object.Resolve();
611  if (group == nullptr || group->type != SGT_RESULT) return 0;
612  return group->GetResult() - 0x42D;
613 }
614 
624 SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint layout, uint edge_info)
625 {
626  /* callback_param1 == 2 means we are resolving the foundation sprites. */
627  StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, 2, layout | (edge_info << 16));
628 
629  const SpriteGroup *group = object.Resolve();
630  if (group == nullptr || group->type != SGT_RESULT) return 0;
631 
632  /* Note: SpriteGroup::Resolve zeroes all registers, so register 0x100 is initialised to 0. (compatibility) */
633  return group->GetResult() + GetRegister(0x100);
634 }
635 
636 
637 uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile)
638 {
639  StationResolverObject object(statspec, st, tile, callback, param1, param2);
640  return object.ResolveCallback();
641 }
642 
653 CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_tile, const StationSpec *statspec, Axis axis, byte plat_len, byte numtracks)
654 {
655  TileIndexDiff diff = cur_tile - north_tile;
656  Slope slope = GetTileSlope(cur_tile);
657 
658  StationResolverObject object(statspec, nullptr, cur_tile, CBID_STATION_LAND_SLOPE_CHECK,
659  (slope << 4) | (slope ^ (axis == AXIS_Y && HasBit(slope, CORNER_W) != HasBit(slope, CORNER_E) ? SLOPE_EW : 0)),
660  (numtracks << 24) | (plat_len << 16) | (axis == AXIS_Y ? TileX(diff) << 8 | TileY(diff) : TileY(diff) << 8 | TileX(diff)));
661  object.station_scope.axis = axis;
662 
663  uint16 cb_res = object.ResolveCallback();
664 
665  /* Failed callback means success. */
666  if (cb_res == CALLBACK_FAILED) return CommandCost();
667 
668  /* The meaning of bit 10 is inverted for a grf version < 8. */
669  if (statspec->grf_prop.grffile->grf_version < 8) ToggleBit(cb_res, 10);
670  return GetErrorMessageFromLocationCallbackResult(cb_res, statspec->grf_prop.grffile, STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
671 }
672 
673 
681 int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exec)
682 {
683  uint i;
684 
685  if (statspec == nullptr || st == nullptr) return 0;
686 
687  for (i = 1; i < st->num_specs && i < NUM_STATIONSSPECS_PER_STATION; i++) {
688  if (st->speclist[i].spec == nullptr && st->speclist[i].grfid == 0) break;
689  }
690 
691  if (i == NUM_STATIONSSPECS_PER_STATION) {
692  /* As final effort when the spec list is already full...
693  * try to find the same spec and return that one. This might
694  * result in slightly "wrong" (as per specs) looking stations,
695  * but it's fairly unlikely that one reaches the limit anyways.
696  */
697  for (i = 1; i < st->num_specs && i < NUM_STATIONSSPECS_PER_STATION; i++) {
698  if (st->speclist[i].spec == statspec) return i;
699  }
700 
701  return -1;
702  }
703 
704  if (exec) {
705  if (i >= st->num_specs) {
706  st->num_specs = i + 1;
707  st->speclist = ReallocT(st->speclist, st->num_specs);
708 
709  if (st->num_specs == 2) {
710  /* Initial allocation */
711  st->speclist[0].spec = nullptr;
712  st->speclist[0].grfid = 0;
713  st->speclist[0].localidx = 0;
714  }
715  }
716 
717  st->speclist[i].spec = statspec;
718  st->speclist[i].grfid = statspec->grf_prop.grffile->grfid;
719  st->speclist[i].localidx = statspec->grf_prop.local_id;
720 
722  }
723 
724  return i;
725 }
726 
727 
734 void DeallocateSpecFromStation(BaseStation *st, byte specindex)
735 {
736  /* specindex of 0 (default) is never freeable */
737  if (specindex == 0) return;
738 
739  ETileArea area = ETileArea(st, INVALID_TILE, TA_WHOLE);
740  /* Check all tiles over the station to check if the specindex is still in use */
741  TILE_AREA_LOOP(tile, area) {
742  if (st->TileBelongsToRailStation(tile) && GetCustomStationSpecIndex(tile) == specindex) {
743  return;
744  }
745  }
746 
747  /* This specindex is no longer in use, so deallocate it */
748  st->speclist[specindex].spec = nullptr;
749  st->speclist[specindex].grfid = 0;
750  st->speclist[specindex].localidx = 0;
751 
752  /* If this was the highest spec index, reallocate */
753  if (specindex == st->num_specs - 1) {
754  for (; st->speclist[st->num_specs - 1].grfid == 0 && st->num_specs > 1; st->num_specs--) {}
755 
756  if (st->num_specs > 1) {
757  st->speclist = ReallocT(st->speclist, st->num_specs);
758  } else {
759  free(st->speclist);
760  st->num_specs = 0;
761  st->speclist = nullptr;
762  st->cached_anim_triggers = 0;
763  st->cached_cargo_triggers = 0;
764  return;
765  }
766  }
767 
769 }
770 
781 bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station)
782 {
783  const DrawTileSprites *sprites = nullptr;
784  const RailtypeInfo *rti = GetRailTypeInfo(railtype);
785  PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company);
786  uint tile = 2;
787 
788  const StationSpec *statspec = StationClass::Get(sclass)->GetSpec(station);
789  if (statspec == nullptr) return false;
790 
792  uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, nullptr, INVALID_TILE);
793  if (callback != CALLBACK_FAILED) tile = callback;
794  }
795 
796  uint32 total_offset = rti->GetRailtypeSpriteOffset();
797  uint32 relocation = 0;
798  uint32 ground_relocation = 0;
799  const NewGRFSpriteLayout *layout = nullptr;
800  DrawTileSprites tmp_rail_layout;
801 
802  if (statspec->renderdata == nullptr) {
803  sprites = GetStationTileLayout(STATION_RAIL, tile + axis);
804  } else {
805  layout = &statspec->renderdata[(tile < statspec->tiles) ? tile + axis : (uint)axis];
806  if (!layout->NeedsPreprocessing()) {
807  sprites = layout;
808  layout = nullptr;
809  }
810  }
811 
812  if (layout != nullptr) {
813  /* Sprite layout which needs preprocessing */
814  bool separate_ground = HasBit(statspec->flags, SSF_SEPARATE_GROUND);
815  uint32 var10_values = layout->PrepareLayout(total_offset, rti->fallback_railtype, 0, 0, separate_ground);
816  uint8 var10;
817  FOR_EACH_SET_BIT(var10, var10_values) {
818  uint32 var10_relocation = GetCustomStationRelocation(statspec, nullptr, INVALID_TILE, var10);
819  layout->ProcessRegisters(var10, var10_relocation, separate_ground);
820  }
821 
822  tmp_rail_layout.seq = layout->GetLayout(&tmp_rail_layout.ground);
823  sprites = &tmp_rail_layout;
824  total_offset = 0;
825  } else {
826  /* Simple sprite layout */
827  ground_relocation = relocation = GetCustomStationRelocation(statspec, nullptr, INVALID_TILE, 0);
829  ground_relocation = GetCustomStationRelocation(statspec, nullptr, INVALID_TILE, 1);
830  }
831  ground_relocation += rti->fallback_railtype;
832  }
833 
834  SpriteID image = sprites->ground.sprite;
835  PaletteID pal = sprites->ground.pal;
836  RailTrackOffset overlay_offset;
837  if (rti->UsesOverlay() && SplitGroundSpriteForOverlay(nullptr, &image, &overlay_offset)) {
839  DrawSprite(image, PAL_NONE, x, y);
840  DrawSprite(ground + overlay_offset, PAL_NONE, x, y);
841  } else {
842  image += HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE) ? ground_relocation : total_offset;
843  if (HasBit(pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) pal += ground_relocation;
844  DrawSprite(image, GroundSpritePaletteTransform(image, pal, palette), x, y);
845  }
846 
847  DrawRailTileSeqInGUI(x, y, sprites, total_offset, relocation, palette);
848 
849  return true;
850 }
851 
852 
853 const StationSpec *GetStationSpec(TileIndex t)
854 {
855  if (!IsCustomStationSpecIndex(t)) return nullptr;
856 
857  const BaseStation *st = BaseStation::GetByTile(t);
858  uint specindex = GetCustomStationSpecIndex(t);
859  return specindex < st->num_specs ? st->speclist[specindex].spec : nullptr;
860 }
861 
862 
870 {
871  const StationSpec *statspec = GetStationSpec(tile);
872 
873  return statspec != nullptr && HasBit(statspec->blocked, GetStationGfx(tile));
874 }
875 
883 {
884  const StationSpec *statspec = GetStationSpec(tile);
885  uint gfx = GetStationGfx(tile);
886  /* Default stations do not draw pylons under roofs (gfx >= 4) */
887  return statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4;
888 }
889 
897 {
898  const StationSpec *statspec = GetStationSpec(tile);
899  return statspec == nullptr || !HasBit(statspec->wires, GetStationGfx(tile));
900 }
901 
903 uint16 GetAnimStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, int extra_data)
904 {
905  return GetStationCallback(callback, param1, param2, statspec, st, tile);
906 }
907 
909 struct StationAnimationBase : public AnimationBase<StationAnimationBase, StationSpec, BaseStation, int, GetAnimStationCallback> {
910  static const CallbackID cb_animation_speed = CBID_STATION_ANIMATION_SPEED;
911  static const CallbackID cb_animation_next_frame = CBID_STATION_ANIM_NEXT_FRAME;
912 
913  static const StationCallbackMask cbm_animation_speed = CBM_STATION_ANIMATION_SPEED;
914  static const StationCallbackMask cbm_animation_next_frame = CBM_STATION_ANIMATION_NEXT_FRAME;
915 };
916 
917 void AnimateStationTile(TileIndex tile)
918 {
919  const StationSpec *ss = GetStationSpec(tile);
920  if (ss == nullptr) return;
921 
923 }
924 
925 void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type)
926 {
927  /* List of coverage areas for each animation trigger */
928  static const TriggerArea tas[] = {
929  TA_TILE, TA_WHOLE, TA_WHOLE, TA_PLATFORM, TA_PLATFORM, TA_PLATFORM, TA_WHOLE
930  };
931 
932  /* Get Station if it wasn't supplied */
933  if (st == nullptr) st = BaseStation::GetByTile(tile);
934 
935  /* Check the cached animation trigger bitmask to see if we need
936  * to bother with any further processing. */
937  if (!HasBit(st->cached_anim_triggers, trigger)) return;
938 
939  uint16 random_bits = Random();
940  ETileArea area = ETileArea(st, tile, tas[trigger]);
941 
942  /* Check all tiles over the station to check if the specindex is still in use */
943  TILE_AREA_LOOP(tile, area) {
944  if (st->TileBelongsToRailStation(tile)) {
945  const StationSpec *ss = GetStationSpec(tile);
946  if (ss != nullptr && HasBit(ss->animation.triggers, trigger)) {
947  CargoID cargo;
948  if (cargo_type == CT_INVALID) {
949  cargo = CT_INVALID;
950  } else {
951  cargo = ss->grf_prop.grffile->cargo_map[cargo_type];
952  }
953  StationAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIM_START_STOP, ss, st, tile, (random_bits << 16) | Random(), (uint8)trigger | (cargo << 8));
954  }
955  }
956  }
957 }
958 
967 {
968  /* List of coverage areas for each animation trigger */
969  static const TriggerArea tas[] = {
970  TA_WHOLE, TA_WHOLE, TA_PLATFORM, TA_PLATFORM, TA_PLATFORM, TA_PLATFORM
971  };
972 
973  /* Get Station if it wasn't supplied */
974  if (st == nullptr) st = Station::GetByTile(tile);
975 
976  /* Check the cached cargo trigger bitmask to see if we need
977  * to bother with any further processing. */
978  if (st->cached_cargo_triggers == 0) return;
979  if (cargo_type != CT_INVALID && !HasBit(st->cached_cargo_triggers, cargo_type)) return;
980 
981  uint32 whole_reseed = 0;
982  ETileArea area = ETileArea(st, tile, tas[trigger]);
983 
984  CargoTypes empty_mask = 0;
985  if (trigger == SRT_CARGO_TAKEN) {
986  /* Create a bitmask of completely empty cargo types to be matched */
987  for (CargoID i = 0; i < NUM_CARGO; i++) {
988  if (st->goods[i].cargo.TotalCount() == 0) {
989  SetBit(empty_mask, i);
990  }
991  }
992  }
993 
994  /* Store triggers now for var 5F */
995  SetBit(st->waiting_triggers, trigger);
996  uint32 used_triggers = 0;
997 
998  /* Check all tiles over the station to check if the specindex is still in use */
999  TILE_AREA_LOOP(tile, area) {
1000  if (st->TileBelongsToRailStation(tile)) {
1001  const StationSpec *ss = GetStationSpec(tile);
1002  if (ss == nullptr) continue;
1003 
1004  /* Cargo taken "will only be triggered if all of those
1005  * cargo types have no more cargo waiting." */
1006  if (trigger == SRT_CARGO_TAKEN) {
1007  if ((ss->cargo_triggers & ~empty_mask) != 0) continue;
1008  }
1009 
1010  if (cargo_type == CT_INVALID || HasBit(ss->cargo_triggers, cargo_type)) {
1011  StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0);
1012  object.waiting_triggers = st->waiting_triggers;
1013 
1014  const SpriteGroup *group = object.Resolve();
1015  if (group == nullptr) continue;
1016 
1017  used_triggers |= object.used_triggers;
1018 
1019  uint32 reseed = object.GetReseedSum();
1020  if (reseed != 0) {
1021  whole_reseed |= reseed;
1022  reseed >>= 16;
1023 
1024  /* Set individual tile random bits */
1025  uint8 random_bits = GetStationTileRandomBits(tile);
1026  random_bits &= ~reseed;
1027  random_bits |= Random() & reseed;
1028  SetStationTileRandomBits(tile, random_bits);
1029 
1030  MarkTileDirtyByTile(tile);
1031  }
1032  }
1033  }
1034  }
1035 
1036  /* Update whole station random bits */
1037  st->waiting_triggers &= ~used_triggers;
1038  if ((whole_reseed & 0xFFFF) != 0) {
1039  st->random_bits &= ~whole_reseed;
1040  st->random_bits |= Random() & whole_reseed;
1041  }
1042 }
1043 
1049 {
1050  st->cached_anim_triggers = 0;
1051  st->cached_cargo_triggers = 0;
1052 
1053  /* Combine animation trigger bitmask for all station specs
1054  * of this station. */
1055  for (uint i = 0; i < st->num_specs; i++) {
1056  const StationSpec *ss = st->speclist[i].spec;
1057  if (ss != nullptr) {
1058  st->cached_anim_triggers |= ss->animation.triggers;
1060  }
1061  }
1062 }
1063 
Implementation of the NewGRF class&#39; functions.
void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoID cargo_type)
Trigger station randomisation.
static void Swap(T &a, T &b)
Type safe swap operation.
Definition: math_func.hpp:275
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:18
Callback 141 needs random bits.
Trigger station when cargo is completely taken.
Use callback to select a sprite layout to use.
NewGRF handling of rail types.
static const RailtypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition: rail.h:304
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
static bool IsCustomStationSpecIndex(TileIndex t)
Is there a custom rail station spec on this tile?
Definition: station_map.h:469
Waypoint class.
void DeallocateSpecFromStation(BaseStation *st, byte specindex)
Deallocate a StationSpec from a Station.
GrfSpecFeature GetFeature() const override
Get the feature number being resolved for.
Base class for roadstops.
bool HasVehicleEverTriedLoading() const
Reports whether a vehicle has ever tried to load the cargo at this station.
Definition: station_base.h:267
uint16 triggers
The triggers that trigger animation.
StationScopeResolver station_scope
The station scope resolver.
#define DAYS_TILL_ORIGINAL_BASE_YEAR
The offset in days from the &#39;_date == 0&#39; till &#39;ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)&#39;.
Definition: date_type.h:80
bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station)
Draw representation of a station tile for GUI purposes.
uint8 num_specs
Number of specs in the speclist.
int32 TileIndexDiff
An offset value between to tiles.
Definition: map_func.h:154
TownScopeResolver * GetTown()
Get the town scope associated with a station, if it exists.
static T ToggleBit(T &x, const uint8 y)
Toggles a bit in a variable.
Northwest.
West.
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:250
Functions related to debugging.
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrackOffset *overlay_offset)
Check whether a sprite is a track sprite, which can be replaced by a non-track ground sprite and a ra...
bool CanStationTileHaveWires(TileIndex tile)
Check if a rail station tile shall have wires when electrified.
CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoID.
Interface for SpriteGroup-s to access the gamestate.
uint32 GetTerrainType(TileIndex tile, TileContext context)
Function used by houses (and soon industries) to get information on type of "terrain" the tile it is ...
Maximal number of cargo types in a game.
Definition: cargo_type.h:64
Set when cargo was delivered for final delivery during the current STATION_ACCEPTANCE_TICKS interval...
Definition: station_base.h:211
Specification of a cargo type.
Definition: cargotype.h:55
Station specification.
Set when cargo was delivered for final delivery this month.
Definition: station_base.h:205
uint TotalCount() const
Returns total count of cargo at the station, including cargo which is already reserved for loading...
Definition: cargopacket.h:526
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:205
TileArea train_station
Tile area the train &#39;station&#39; part covers.
static bool IsExpected(const BaseStation *st)
Helper for checking whether the given station is of this type.
uint DaysInTransit() const
Returns average number of days in transit for a cargo entity.
Definition: cargopacket.h:255
Set when using the callback resolve system, but not to resolve a callback.
Stores station stats for a single cargo.
Definition: station_base.h:170
#define INSTANTIATE_NEWGRF_CLASS_METHODS(name, Tspec, Tid, Tmax)
Force instantiation of the methods so we don&#39;t get linker errors.
uint32 GetRandomBits() const override
Get a few random bits.
const DrawTileSeqStruct * GetLayout(PalSpriteID *ground) const
Returns the result spritelayout after preprocessing.
virtual void GetTileArea(TileArea *ta, StationType type) const =0
Get the tile area for a given station type.
byte num_loaded
Number of loaded groups.
#define FOR_EACH_SET_BIT(bitpos_var, bitset_value)
Do an operation for each set set bit in a value.
Common return value for all commands.
Definition: command_type.h:23
uint32 reseed[VSG_END]
Collects bits to rerandomise while triggering triggers.
static void ChangeAnimationFrame(CallbackID cb, const StationSpec *spec, BaseStation *obj, TileIndex tile, uint32 random_bits, uint32 trigger, int extra_data=0)
Check a callback to determine what the next animation step is and execute that step.
bool IsUIAvailable(uint index) const
Check whether the spec will be available to the user at some point in time.
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition: station_base.h:255
bool HasRating() const
Does this cargo have a rating at this station?
Definition: station_base.h:273
uint tiles
Number of tile layouts.
uint16 w
The width of the area.
Definition: tilearea_type.h:18
Use a custom next frame callback.
void StationUpdateCachedTriggers(BaseStation *st)
Update the cached animation trigger bitmask for a station.
CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, const GRFFile *grffile, StringID default_error)
Get the error message from a shape/location/slope check callback result.
GoodsEntry goods[NUM_CARGO]
Goods at this station.
Definition: station_base.h:479
Southwest.
static void AnimateTile(const StationSpec *spec, BaseStation *obj, TileIndex tile, bool random_animation, int extra_data=0)
Animate a single tile.
static T SB(T &x, const uint8 s, const uint8 n, const U d)
Set n bits in x starting at bit s to d.
static uint GetCustomStationSpecIndex(TileIndex t)
Get the custom station spec for this tile.
Definition: station_map.h:493
North.
const DrawTileSeqStruct * seq
Array of child sprites. Terminated with a terminator entry.
Definition: sprite.h:60
CargoTypes cargo_triggers
Bitmask of cargo types which cause trigger re-randomizing.
static Station * From(BaseStation *st)
Converts a BaseStation to SpecializedStation with type checking.
This struct contains all the info that is needed to draw and construct tracks.
Definition: rail.h:124
uint32 GetDebugID() const override
Get an identifier for the item being resolved.
Callback done for each tile of a station to check the slope.
Station is a waypoint (NewGRF only!)
Definition: station_type.h:70
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
static bool HasStationRail(TileIndex t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint...
Definition: station_map.h:135
Invalid cargo type.
Definition: cargo_type.h:68
Set when cargo was delivered for final delivery last month.
Definition: station_base.h:199
Slope GetTileSlope(TileIndex tile, int *h)
Return the slope of a given tile inside the map.
Definition: tile_map.cpp:59
static bool IsCompatibleTrainStationTile(TileIndex test_tile, TileIndex station_tile)
Check if a tile is a valid continuation to a railstation tile.
Definition: station_map.h:378
uint32 GetTriggers() const override
Get the triggers.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold...
Definition: town_cmd.cpp:3534
static void DrawRailTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32 total_offset, uint32 newgrf_offset, PaletteID default_palette)
Draw tile sprite sequence in GUI with railroad specifics.
Definition: sprite.h:99
Struct containing information relating to NewGRF classes for stations and airports.
Definition: newgrf_class.h:19
GrfSpecFeature
Definition: newgrf.h:66
bool TileBelongsToRailStation(TileIndex tile) const override
Check whether a specific tile belongs to this station.
Definition: station_base.h:513
byte pylons
Bitmask of base tiles (0 - 7) which should contain elrail pylons.
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context, uint *num_results)
Get the sprite to draw for the given tile.
SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint32 var10)
Resolve sprites for drawing a station tile.
static uint32 GetRegister(uint i)
Gets the value of a so-called newgrf "register".
byte rating
Station rating for this cargo.
Definition: station_base.h:235
static TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition: map_func.h:341
virtual const SpriteGroup * Resolve(ResolverObject &object) const
Base sprite group resolver.
uint8 valid
Bits indicating what variable is valid (for each bit, 0 is invalid, 1 is valid).
Action 2 handling.
static void SetStationTileRandomBits(TileIndex t, byte random_bits)
Set the random bits for a station tile.
Definition: station_map.h:505
TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets, Axis axis)
Get the tile at the given offset.
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
Southeast.
const SpriteGroup ** loaded
List of loaded groups (can be SpriteIDs or Callback results)
The y axis.
uint32 PrepareLayout(uint32 orig_offset, uint32 newgrf_ground_offset, uint32 newgrf_offset, uint constr_stage, bool separate_ground) const
Prepares a sprite layout before resolving action-1-2-3 chains.
Called to indicate how long the current animation frame should last.
static struct @31 _svc
Station variable cache This caches &#39;expensive&#39; station variable lookups which iterate over several ti...
Customize the animation speed of the station.
static bool HasStationReservation(TileIndex t)
Get the reservation state of the rail station.
Definition: station_map.h:393
static bool IsRailStationTile(TileIndex t)
Is this tile a station tile and a rail station?
Definition: station_map.h:102
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:58
const SpriteGroup * ResolveReal(const RealSpriteGroup *group) const override
Get the real sprites of the grf.
East.
Southeast.
GRFFilePropsBase< NUM_CARGO+3 > grf_prop
Properties related the the grf file.
byte status
Status of this cargo, see GoodsEntryStatus.
Definition: station_base.h:226
static bool HasStationTileRail(TileIndex t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint...
Definition: station_map.h:146
#define TILE_AREA_LOOP(var, ta)
A loop which iterates over the tiles of a TileArea.
int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exec)
Allocate a StationSpec to a Station.
Definition of base types and functions in a cross-platform compatible way.
Function implementations related to NewGRF animation.
A number of safeguards to prevent using unsafe methods.
Scope resolver for a town.
Definition: newgrf_town.h:22
Direction
Defines the 8 directions on the map.
static PaletteID GroundSpritePaletteTransform(SpriteID image, PaletteID pal, PaletteID default_pal)
Applies PALETTE_MODIFIER_COLOUR to a palette entry of a ground sprite.
Definition: sprite.h:168
Base of waypoints.
static Axis GetRailStationAxis(TileIndex t)
Get the rail direction of a rail station.
Definition: station_map.h:337
Called for periodically starting or stopping the animation.
uint32 used_triggers
Subset of cur_triggers, which actually triggered some rerandomisation. (scope independent) ...
void ProcessRegisters(uint8 resolved_var10, uint32 resolved_sprite, bool separate_ground) const
Evaluates the register modifiers and integrates them into the preprocessed sprite layout...
static TileIndex FindRailStationEnd(TileIndex tile, TileIndexDiff delta, bool check_type, bool check_axis)
Find the end of a railway station, from the tile, in the direction of delta.
Represents the covered area of e.g.
Definition: tilearea_type.h:16
static T * ReallocT(T *t_ptr, size_t num_elements)
Simplified reallocation function that allocates the specified number of elements of the given type...
Definition: alloc_func.hpp:111
TrackBits
Bitfield corresponding to Track.
Definition: track_type.h:38
Set when a sprite originates from an Action 1.
Definition: sprites.h:1524
StationSpecList * speclist
List of station specs of this station.
South.
StationCallbackMask
Callback masks for stations.
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1938
byte wires
Bitmask of base tiles (0 - 7) which should contain elrail wires.
const SpriteGroup ** loading
List of loading groups (can be SpriteIDs or Callback results)
TownScopeResolver * town_scope
The town scope resolver (created on the first call).
uint8 cargo_map[NUM_CARGO]
Inverse cargo translation table (CargoID -> local ID)
Definition: newgrf.h:127
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
byte last_speed
Maximum speed (up to 255) of the last vehicle that tried to load this cargo.
Definition: station_base.h:246
uint8 cached_anim_triggers
NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen...
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:40
NewGRF supplied spritelayout.
static DiagDirection GetTunnelBridgeDirection(TileIndex t)
Get the direction pointing to the other end.
byte last_age
Age in years (up to 255) of the last vehicle that tried to load this cargo.
Definition: station_base.h:252
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
static StationGfx GetStationGfx(TileIndex t)
Get the station graphics of this tile.
Definition: station_map.h:68
east and west corner are raised
Definition: slope_type.h:59
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition: landscape.cpp:589
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:137
static TrackBits DiagdirReachesTracks(DiagDirection diagdir)
Returns all tracks that can be reached when entering a tile from a given (diagonal) direction...
Definition: track_func.h:581
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:17
byte flags
Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size...
SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint layout, uint edge_info)
Resolve the sprites for custom station foundations.
StationAnimationTrigger
Animation triggers for station.
The X axis.
byte num_loading
Number of loading groups.
Transport by train.
Set when a vehicle ever delivered cargo to the station for final delivery.
Definition: station_base.h:193
static BaseStation * GetByTile(TileIndex tile)
Get the base station belonging to a specific tile.
CargoID cargo_type
Type of cargo of the station.
Functions related to companies.
const struct StationSpec * statspec
Station (type) specification.
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:28
No track.
Definition: track_type.h:39
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:59
Header file for NewGRF stations.
RailType
Enumeration for all possible railtypes.
Definition: rail_type.h:27
struct BaseStation * st
Instance of the station.
StationID Source() const
Returns source of the first cargo packet in this list.
Definition: cargopacket.h:497
bool IsStationTileBlocked(TileIndex tile)
Check whether a rail station tile is NOT traversable.
CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_tile, const StationSpec *statspec, Axis axis, byte plat_len, byte numtracks)
Check the slope of a tile of a new station.
Tunnel entry/exit and bridge heads.
Definition: tile_type.h:50
StationClassID
bool NeedsPreprocessing() const
Tests whether this spritelayout needs preprocessing by PrepareLayout() and ProcessRegisters(), or whether it can be used directly.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8)
Common part of station var 0x67, house var 0x62, indtile var 0x60, industry var 0x62.
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
Use different sprite set for ground sprites.
Helper class for a unified approach to NewGRF animation.
uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, int y, bool centred)
Evaluate a tile&#39;s position within a station, and return the result in a bit-stuffed format...
virtual bool TileBelongsToRailStation(TileIndex tile) const =0
Check whether a specific tile belongs to this station.
Cargo support for NewGRFs.
byte fallback_railtype
Original railtype number to use when drawing non-newgrf railtypes, or when drawing stations...
Definition: rail.h:198
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:215
CargoTypes cached_cargo_triggers
NOSAVE: Combined cargo trigger bitmask.
Called to determine station tile next animation frame.
CallbackID callback
Callback being resolved.
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
uint16 GetAnimStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, int extra_data)
Wrapper for animation control, see GetStationCallback.
Slope
Enumeration for the slope-type.
Definition: slope_type.h:48
uint32 GetCompanyInfo(CompanyID owner, const Livery *l)
Returns company information like in vehicle var 43 or station var 43.
Maximum number of classes.
A tile of a station.
Definition: tile_type.h:46
Town data structure.
Definition: town.h:53
static Station * GetByTile(TileIndex tile)
Get the station belonging to a specific tile.
static TrackBits TrackStatusToTrackBits(TrackStatus ts)
Returns the present-track-information of a TrackStatus.
Definition: track_func.h:371
Northwest.
bool CanStationTileHavePylons(TileIndex tile)
Check if a rail station tile shall have pylons when electrified.
Main group of ground images.
Definition: rail.h:49
static NewGRFClass * Get(Tid cls_id)
Get a particular class.
uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile)
Perform a reverse railtype lookup to get the GRF internal ID.
uint GetRailtypeSpriteOffset() const
Offset between the current railtype and normal rail.
Definition: rail.h:292
static TileIndexDiff TileOffsByDir(Direction dir)
Convert a Direction to a TileIndexDiff.
Definition: map_func.h:355
Same as AT_LARGE.
Northeast.
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:45
CargoID Index() const
Determines index of this cargospec.
Definition: cargotype.h:88
uint8 localidx
Station ID within GRF of station.
uint16 local_id
id defined by the grf file for this entity
static void InsertDefaults()
Initialise the defaults.
Functions that have tunnels and bridges in common.
static TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:179
uint16 random_bits
Random bits assigned to this station.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:129
StationRandomTrigger
Randomisation triggers for stations.
RailTrackOffset
Offsets for sprites within an overlay/underlay set.
Definition: rail.h:67
const struct GRFFile * grffile
grf file that introduced this entity
CallbackID
List of implemented NewGRF callbacks.
Station resolver.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Functions related to NewGRF provided sounds.
DiagDirection
Enumeration for diagonal directions.
Set when calling a randomizing trigger (almost undocumented).
byte callback_mask
Bitmask of station callbacks that have to be called.
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:83
Base of the town class.
StationResolverObject(const StationSpec *statspec, BaseStation *st, TileIndex tile, CallbackID callback=CBID_NO_CALLBACK, uint32 callback_param1=0, uint32 callback_param2=0)
Resolver for stations.
Northeast, upper right on your monitor.
Functions to handle the town part of NewGRF towns.
Choose a sprite layout to draw, instead of the standard 0-7 range.
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
NewGRFSpriteLayout * renderdata
Array of tile layouts.
byte waiting_triggers
Waiting triggers (NewGRF) for this station.
Divide cargo amount by station size.
byte time_since_pickup
Number of rating-intervals (up to 255) since the last vehicle tried to load this cargo.
Definition: station_base.h:233
uint32 GetNewGRFVariable(const struct ResolverObject &object, byte variable, byte parameter, bool *available) const override
Helper function to get a NewGRF variable that isn&#39;t implemented by the base class.
static DiagDirection AxisToDiagDir(Axis a)
Converts an Axis to a DiagDirection.
#define TILE_ADD(x, y)
Adds to tiles together.
Definition: map_func.h:244
Flag for an invalid Axis.
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:23
static const uint NUM_STATIONSSPECS_PER_STATION
Maximum number of parts per station.
Base classes/functions for stations.
Date _date
Current date in days (day counter)
Definition: date.cpp:27
Helper class for animation control.
uint16 h
The height of the area.
Definition: tilearea_type.h:19
static byte GetStationTileRandomBits(TileIndex t)
Get the random bits of a station tile.
Definition: station_map.h:517
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:44
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override
Get a variable value.
Base class for all station-ish types.
Station data structure.
Definition: station_base.h:450
Axis
Allow incrementing of DiagDirDiff variables.
Set when the station accepts the cargo currently for final deliveries.
Definition: station_base.h:177
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition: gfx.cpp:973
static RailType GetRailType(TileIndex t)
Gets the rail type of the given tile.
Definition: rail_map.h:115
byte blocked
Bitmask of base tiles (0 - 7) which are blocked to trains.
uint32 grfid
GRF ID of this custom station.
Southwest.
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:24