OpenTTD
newgrf_station.cpp
Go to the documentation of this file.
1 /* $Id: newgrf_station.cpp 27984 2018-03-11 13:19:41Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "debug.h"
14 #include "station_base.h"
15 #include "waypoint_base.h"
16 #include "roadstop_base.h"
17 #include "newgrf_cargo.h"
18 #include "newgrf_station.h"
19 #include "newgrf_spritegroup.h"
20 #include "newgrf_sound.h"
21 #include "newgrf_railtype.h"
22 #include "town.h"
23 #include "newgrf_town.h"
24 #include "company_func.h"
25 #include "tunnelbridge_map.h"
26 #include "newgrf_animation_base.h"
27 #include "newgrf_class_func.h"
28 
29 #include "safeguards.h"
30 
31 
32 template <typename Tspec, typename Tid, Tid Tmax>
34 {
35  /* Set up initial data */
36  classes[0].global_id = 'DFLT';
37  classes[0].name = STR_STATION_CLASS_DFLT;
38  classes[0].Insert(NULL);
39 
40  classes[1].global_id = 'WAYP';
41  classes[1].name = STR_STATION_CLASS_WAYP;
42  classes[1].Insert(NULL);
43 }
44 
45 template <typename Tspec, typename Tid, Tid Tmax>
47 {
48  return true;
49 }
50 
52 
53 static const uint NUM_STATIONSSPECS_PER_STATION = 255;
54 
55 enum TriggerArea {
56  TA_TILE,
57  TA_PLATFORM,
58  TA_WHOLE,
59 };
60 
61 struct ETileArea : TileArea {
62  ETileArea(const BaseStation *st, TileIndex tile, TriggerArea ta)
63  {
64  switch (ta) {
65  default: NOT_REACHED();
66 
67  case TA_TILE:
68  this->tile = tile;
69  this->w = 1;
70  this->h = 1;
71  break;
72 
73  case TA_PLATFORM: {
74  TileIndex start, end;
75  Axis axis = GetRailStationAxis(tile);
77 
78  for (end = tile; IsRailStationTile(end + delta) && IsCompatibleTrainStationTile(end + delta, tile); end += delta) { /* Nothing */ }
79  for (start = tile; IsRailStationTile(start - delta) && IsCompatibleTrainStationTile(start - delta, tile); start -= delta) { /* Nothing */ }
80 
81  this->tile = start;
82  this->w = TileX(end) - TileX(start) + 1;
83  this->h = TileY(end) - TileY(start) + 1;
84  break;
85  }
86 
87  case TA_WHOLE:
88  st->GetTileArea(this, Station::IsExpected(st) ? STATION_RAIL : STATION_WAYPOINT);
89  break;
90  }
91  }
92 };
93 
94 
107 uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, int y, bool centred)
108 {
109  uint32 retval = 0;
110 
111  if (axis == AXIS_X) {
112  Swap(platforms, length);
113  Swap(x, y);
114  }
115 
116  if (centred) {
117  x -= platforms / 2;
118  y -= length / 2;
119  x = Clamp(x, -8, 7);
120  y = Clamp(y, -8, 7);
121  SB(retval, 0, 4, y & 0xF);
122  SB(retval, 4, 4, x & 0xF);
123  } else {
124  SB(retval, 0, 4, min(15, y));
125  SB(retval, 4, 4, min(15, length - y - 1));
126  SB(retval, 8, 4, min(15, x));
127  SB(retval, 12, 4, min(15, platforms - x - 1));
128  }
129  SB(retval, 16, 4, min(15, length));
130  SB(retval, 20, 4, min(15, platforms));
131  SB(retval, 24, 4, tile);
132 
133  return retval;
134 }
135 
136 
145 static TileIndex FindRailStationEnd(TileIndex tile, TileIndexDiff delta, bool check_type, bool check_axis)
146 {
147  byte orig_type = 0;
148  Axis orig_axis = AXIS_X;
149  StationID sid = GetStationIndex(tile);
150 
151  if (check_type) orig_type = GetCustomStationSpecIndex(tile);
152  if (check_axis) orig_axis = GetRailStationAxis(tile);
153 
154  for (;;) {
155  TileIndex new_tile = TILE_ADD(tile, delta);
156 
157  if (!IsTileType(new_tile, MP_STATION) || GetStationIndex(new_tile) != sid) break;
158  if (!HasStationRail(new_tile)) break;
159  if (check_type && GetCustomStationSpecIndex(new_tile) != orig_type) break;
160  if (check_axis && GetRailStationAxis(new_tile) != orig_axis) break;
161 
162  tile = new_tile;
163  }
164  return tile;
165 }
166 
167 
168 static uint32 GetPlatformInfoHelper(TileIndex tile, bool check_type, bool check_axis, bool centred)
169 {
170  int tx = TileX(tile);
171  int ty = TileY(tile);
172  int sx = TileX(FindRailStationEnd(tile, TileDiffXY(-1, 0), check_type, check_axis));
173  int sy = TileY(FindRailStationEnd(tile, TileDiffXY( 0, -1), check_type, check_axis));
174  int ex = TileX(FindRailStationEnd(tile, TileDiffXY( 1, 0), check_type, check_axis)) + 1;
175  int ey = TileY(FindRailStationEnd(tile, TileDiffXY( 0, 1), check_type, check_axis)) + 1;
176 
177  tx -= sx; ex -= sx;
178  ty -= sy; ey -= sy;
179 
180  return GetPlatformInfo(GetRailStationAxis(tile), GetStationGfx(tile), ex, ey, tx, ty, centred);
181 }
182 
183 
184 static uint32 GetRailContinuationInfo(TileIndex tile)
185 {
186  /* Tile offsets and exit dirs for X axis */
187  static const Direction x_dir[8] = { DIR_SW, DIR_NE, DIR_SE, DIR_NW, DIR_S, DIR_E, DIR_W, DIR_N };
188  static const DiagDirection x_exits[8] = { DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SW, DIAGDIR_NE };
189 
190  /* Tile offsets and exit dirs for Y axis */
191  static const Direction y_dir[8] = { DIR_SE, DIR_NW, DIR_SW, DIR_NE, DIR_S, DIR_W, DIR_E, DIR_N };
192  static const DiagDirection y_exits[8] = { DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SE, DIAGDIR_NW };
193 
194  Axis axis = GetRailStationAxis(tile);
195 
196  /* Choose appropriate lookup table to use */
197  const Direction *dir = axis == AXIS_X ? x_dir : y_dir;
198  const DiagDirection *diagdir = axis == AXIS_X ? x_exits : y_exits;
199 
200  uint32 res = 0;
201  uint i;
202 
203  for (i = 0; i < lengthof(x_dir); i++, dir++, diagdir++) {
204  TileIndex neighbour_tile = tile + TileOffsByDir(*dir);
205  TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(neighbour_tile, TRANSPORT_RAIL, 0));
206  if (trackbits != TRACK_BIT_NONE) {
207  /* If there is any track on the tile, set the bit in the second byte */
208  SetBit(res, i + 8);
209 
210  /* With tunnels and bridges the tile has tracks, but they are not necessarily connected
211  * with the next tile because the ramp is not going in the right direction. */
212  if (IsTileType(neighbour_tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(neighbour_tile) != *diagdir) {
213  continue;
214  }
215 
216  /* If any track reaches our exit direction, set the bit in the lower byte */
217  if (trackbits & DiagdirReachesTracks(*diagdir)) SetBit(res, i);
218  }
219  }
220 
221  return res;
222 }
223 
224 
225 /* Station Resolver Functions */
226 /* virtual */ uint32 StationScopeResolver::GetRandomBits() const
227 {
228  return (this->st == NULL ? 0 : this->st->random_bits) | (this->tile == INVALID_TILE ? 0 : GetStationTileRandomBits(this->tile) << 16);
229 }
230 
231 
232 /* virtual */ uint32 StationScopeResolver::GetTriggers() const
233 {
234  return this->st == NULL ? 0 : this->st->waiting_triggers;
235 }
236 
237 
243 static struct {
244  uint32 v40;
245  uint32 v41;
246  uint32 v45;
247  uint32 v46;
248  uint32 v47;
249  uint32 v49;
250  uint8 valid;
251 } _svc;
252 
259 {
260  if (this->town_scope == NULL) {
261  Town *t = NULL;
262  if (this->station_scope.st != NULL) {
263  t = this->station_scope.st->town;
264  } else if (this->station_scope.tile != INVALID_TILE) {
265  t = ClosestTownFromTile(this->station_scope.tile, UINT_MAX);
266  }
267  if (t == NULL) return NULL;
268  this->town_scope = new TownScopeResolver(*this, t, this->station_scope.st == NULL);
269  }
270  return this->town_scope;
271 }
272 
273 /* virtual */ uint32 StationScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
274 {
275  if (this->st == NULL) {
276  /* Station does not exist, so we're in a purchase list or the land slope check callback. */
277  switch (variable) {
278  case 0x40:
279  case 0x41:
280  case 0x46:
281  case 0x47:
282  case 0x49: return 0x2110000; // Platforms, tracks & position
283  case 0x42: return 0; // Rail type (XXX Get current type from GUI?)
284  case 0x43: return GetCompanyInfo(_current_company); // Station owner
285  case 0x44: return 2; // PBS status
286  case 0x67: // Land info of nearby tile
287  if (this->axis != INVALID_AXIS && this->tile != INVALID_TILE) {
288  TileIndex tile = this->tile;
289  if (parameter != 0) tile = GetNearbyTile(parameter, tile, true, this->axis); // only perform if it is required
290 
291  Slope tileh = GetTileSlope(tile);
292  bool swap = (this->axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E));
293 
294  return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8) ^ (swap ? SLOPE_EW : 0);
295  }
296  break;
297 
298  case 0xFA: return Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Build date, clamped to a 16 bit value
299  }
300 
301  *available = false;
302  return UINT_MAX;
303  }
304 
305  switch (variable) {
306  /* Calculated station variables */
307  case 0x40:
308  if (!HasBit(_svc.valid, 0)) { _svc.v40 = GetPlatformInfoHelper(this->tile, false, false, false); SetBit(_svc.valid, 0); }
309  return _svc.v40;
310 
311  case 0x41:
312  if (!HasBit(_svc.valid, 1)) { _svc.v41 = GetPlatformInfoHelper(this->tile, true, false, false); SetBit(_svc.valid, 1); }
313  return _svc.v41;
314 
315  case 0x42: return GetTerrainType(this->tile) | (GetReverseRailTypeTranslation(GetRailType(this->tile), this->statspec->grf_prop.grffile) << 8);
316  case 0x43: return GetCompanyInfo(this->st->owner); // Station owner
317  case 0x44: return HasStationReservation(this->tile) ? 7 : 4; // PBS status
318  case 0x45:
319  if (!HasBit(_svc.valid, 2)) { _svc.v45 = GetRailContinuationInfo(this->tile); SetBit(_svc.valid, 2); }
320  return _svc.v45;
321 
322  case 0x46:
323  if (!HasBit(_svc.valid, 3)) { _svc.v46 = GetPlatformInfoHelper(this->tile, false, false, true); SetBit(_svc.valid, 3); }
324  return _svc.v46;
325 
326  case 0x47:
327  if (!HasBit(_svc.valid, 4)) { _svc.v47 = GetPlatformInfoHelper(this->tile, true, false, true); SetBit(_svc.valid, 4); }
328  return _svc.v47;
329 
330  case 0x49:
331  if (!HasBit(_svc.valid, 5)) { _svc.v49 = GetPlatformInfoHelper(this->tile, false, true, false); SetBit(_svc.valid, 5); }
332  return _svc.v49;
333 
334  case 0x4A: // Animation frame of tile
335  return GetAnimationFrame(this->tile);
336 
337  /* Variables which use the parameter */
338  /* Variables 0x60 to 0x65 and 0x69 are handled separately below */
339  case 0x66: { // Animation frame of nearby tile
340  TileIndex tile = this->tile;
341  if (parameter != 0) tile = GetNearbyTile(parameter, tile);
342  return this->st->TileBelongsToRailStation(tile) ? GetAnimationFrame(tile) : UINT_MAX;
343  }
344 
345  case 0x67: { // Land info of nearby tile
346  Axis axis = GetRailStationAxis(this->tile);
347  TileIndex tile = this->tile;
348  if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required
349 
350  Slope tileh = GetTileSlope(tile);
351  bool swap = (axis == AXIS_Y && HasBit(tileh, CORNER_W) != HasBit(tileh, CORNER_E));
352 
353  return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8) ^ (swap ? SLOPE_EW : 0);
354  }
355 
356  case 0x68: { // Station info of nearby tiles
357  TileIndex nearby_tile = GetNearbyTile(parameter, this->tile);
358 
359  if (!HasStationTileRail(nearby_tile)) return 0xFFFFFFFF;
360 
361  uint32 grfid = this->st->speclist[GetCustomStationSpecIndex(this->tile)].grfid;
362  bool perpendicular = GetRailStationAxis(this->tile) != GetRailStationAxis(nearby_tile);
363  bool same_station = this->st->TileBelongsToRailStation(nearby_tile);
364  uint32 res = GB(GetStationGfx(nearby_tile), 1, 2) << 12 | !!perpendicular << 11 | !!same_station << 10;
365 
366  if (IsCustomStationSpecIndex(nearby_tile)) {
367  const StationSpecList ssl = BaseStation::GetByTile(nearby_tile)->speclist[GetCustomStationSpecIndex(nearby_tile)];
368  res |= 1 << (ssl.grfid != grfid ? 9 : 8) | ssl.localidx;
369  }
370  return res;
371  }
372 
373  /* General station variables */
374  case 0x82: return 50;
375  case 0x84: return this->st->string_id;
376  case 0x86: return 0;
377  case 0xF0: return this->st->facilities;
378  case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
379  }
380 
381  return this->st->GetNewGRFVariable(this->ro, variable, parameter, available);
382 }
383 
384 uint32 Station::GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const
385 {
386  switch (variable) {
387  case 0x48: { // Accepted cargo types
388  CargoID cargo_type;
389  uint32 value = 0;
390 
391  for (cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
392  if (HasBit(this->goods[cargo_type].status, GoodsEntry::GES_ACCEPTANCE)) SetBit(value, cargo_type);
393  }
394  return value;
395  }
396 
397  case 0x8A: return this->had_vehicle_of_type;
398  case 0xF1: return (this->airport.tile != INVALID_TILE) ? this->airport.GetSpec()->ttd_airport_type : ATP_TTDP_LARGE;
399  case 0xF2: return (this->truck_stops != NULL) ? this->truck_stops->status : 0;
400  case 0xF3: return (this->bus_stops != NULL) ? this->bus_stops->status : 0;
401  case 0xF6: return this->airport.flags;
402  case 0xF7: return GB(this->airport.flags, 8, 8);
403  }
404 
405  /* Handle cargo variables with parameter, 0x60 to 0x65 and 0x69 */
406  if ((variable >= 0x60 && variable <= 0x65) || variable == 0x69) {
407  CargoID c = GetCargoTranslation(parameter, object.grffile);
408 
409  if (c == CT_INVALID) {
410  switch (variable) {
411  case 0x62: return 0xFFFFFFFF;
412  case 0x64: return 0xFF00;
413  default: return 0;
414  }
415  }
416  const GoodsEntry *ge = &this->goods[c];
417 
418  switch (variable) {
419  case 0x60: return min(ge->cargo.TotalCount(), 4095);
420  case 0x61: return ge->HasVehicleEverTriedLoading() ? ge->time_since_pickup : 0;
421  case 0x62: return ge->HasRating() ? ge->rating : 0xFFFFFFFF;
422  case 0x63: return ge->cargo.DaysInTransit();
423  case 0x64: return ge->HasVehicleEverTriedLoading() ? ge->last_speed | (ge->last_age << 8) : 0xFF00;
424  case 0x65: return GB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1) << 3;
425  case 0x69: {
426  assert_compile((int)GoodsEntry::GES_EVER_ACCEPTED + 1 == (int)GoodsEntry::GES_LAST_MONTH);
427  assert_compile((int)GoodsEntry::GES_EVER_ACCEPTED + 2 == (int)GoodsEntry::GES_CURRENT_MONTH);
428  assert_compile((int)GoodsEntry::GES_EVER_ACCEPTED + 3 == (int)GoodsEntry::GES_ACCEPTED_BIGTICK);
429  return GB(ge->status, GoodsEntry::GES_EVER_ACCEPTED, 4);
430  }
431  }
432  }
433 
434  /* Handle cargo variables (deprecated) */
435  if (variable >= 0x8C && variable <= 0xEC) {
436  const GoodsEntry *g = &this->goods[GB(variable - 0x8C, 3, 4)];
437  switch (GB(variable - 0x8C, 0, 3)) {
438  case 0: return g->cargo.TotalCount();
439  case 1: return GB(min(g->cargo.TotalCount(), 4095), 0, 4) | (GB(g->status, GoodsEntry::GES_ACCEPTANCE, 1) << 7);
440  case 2: return g->time_since_pickup;
441  case 3: return g->rating;
442  case 4: return g->cargo.Source();
443  case 5: return g->cargo.DaysInTransit();
444  case 6: return g->last_speed;
445  case 7: return g->last_age;
446  }
447  }
448 
449  DEBUG(grf, 1, "Unhandled station variable 0x%X", variable);
450 
451  *available = false;
452  return UINT_MAX;
453 }
454 
455 uint32 Waypoint::GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const
456 {
457  switch (variable) {
458  case 0x48: return 0; // Accepted cargo types
459  case 0x8A: return HVOT_WAYPOINT;
460  case 0xF1: return 0; // airport type
461  case 0xF2: return 0; // truck stop status
462  case 0xF3: return 0; // bus stop status
463  case 0xF6: return 0; // airport flags
464  case 0xF7: return 0; // airport flags cont.
465  }
466 
467  /* Handle cargo variables with parameter, 0x60 to 0x65 */
468  if (variable >= 0x60 && variable <= 0x65) {
469  return 0;
470  }
471 
472  /* Handle cargo variables (deprecated) */
473  if (variable >= 0x8C && variable <= 0xEC) {
474  switch (GB(variable - 0x8C, 0, 3)) {
475  case 3: return INITIAL_STATION_RATING;
476  case 4: return INVALID_STATION;
477  default: return 0;
478  }
479  }
480 
481  DEBUG(grf, 1, "Unhandled station variable 0x%X", variable);
482 
483  *available = false;
484  return UINT_MAX;
485 }
486 
487 /* virtual */ const SpriteGroup *StationResolverObject::ResolveReal(const RealSpriteGroup *group) const
488 {
489  if (this->station_scope.st == NULL || this->station_scope.statspec->cls_id == STAT_CLASS_WAYP) {
490  return group->loading[0];
491  }
492 
493  uint cargo = 0;
494  const Station *st = Station::From(this->station_scope.st);
495 
496  switch (this->station_scope.cargo_type) {
497  case CT_INVALID:
498  case CT_DEFAULT_NA:
499  case CT_PURCHASE:
500  cargo = 0;
501  break;
502 
503  case CT_DEFAULT:
504  for (CargoID cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
505  cargo += st->goods[cargo_type].cargo.TotalCount();
506  }
507  break;
508 
509  default:
510  cargo = st->goods[this->station_scope.cargo_type].cargo.TotalCount();
511  break;
512  }
513 
514  if (HasBit(this->station_scope.statspec->flags, SSF_DIV_BY_STATION_SIZE)) cargo /= (st->train_station.w + st->train_station.h);
515  cargo = min(0xfff, cargo);
516 
517  if (cargo > this->station_scope.statspec->cargo_threshold) {
518  if (group->num_loading > 0) {
519  uint set = ((cargo - this->station_scope.statspec->cargo_threshold) * group->num_loading) / (4096 - this->station_scope.statspec->cargo_threshold);
520  return group->loading[set];
521  }
522  } else {
523  if (group->num_loaded > 0) {
524  uint set = (cargo * group->num_loaded) / (this->station_scope.statspec->cargo_threshold + 1);
525  return group->loaded[set];
526  }
527  }
528 
529  return group->loading[0];
530 }
531 
542  CallbackID callback, uint32 callback_param1, uint32 callback_param2)
543  : ResolverObject(statspec->grf_prop.grffile, callback, callback_param1, callback_param2),
544  station_scope(*this, statspec, st, tile), town_scope(NULL)
545 {
546  /* Invalidate all cached vars */
547  _svc.valid = 0;
548 
549  CargoID ctype = CT_DEFAULT_NA;
550 
551  if (this->station_scope.st == NULL) {
552  /* No station, so we are in a purchase list */
553  ctype = CT_PURCHASE;
554  } else if (Station::IsExpected(this->station_scope.st)) {
555  const Station *st = Station::From(this->station_scope.st);
556  /* Pick the first cargo that we have waiting */
557  const CargoSpec *cs;
558  FOR_ALL_CARGOSPECS(cs) {
559  if (this->station_scope.statspec->grf_prop.spritegroup[cs->Index()] != NULL &&
560  st->goods[cs->Index()].cargo.TotalCount() > 0) {
561  ctype = cs->Index();
562  break;
563  }
564  }
565  }
566 
567  if (this->station_scope.statspec->grf_prop.spritegroup[ctype] == NULL) {
568  ctype = CT_DEFAULT;
569  }
570 
571  /* Remember the cargo type we've picked */
572  this->station_scope.cargo_type = ctype;
574 }
575 
576 StationResolverObject::~StationResolverObject()
577 {
578  delete this->town_scope;
579 }
580 
589 SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint32 var10)
590 {
591  StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, var10);
592  const SpriteGroup *group = object.Resolve();
593  if (group == NULL || group->type != SGT_RESULT) return 0;
594  return group->GetResult() - 0x42D;
595 }
596 
606 SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint layout, uint edge_info)
607 {
608  /* callback_param1 == 2 means we are resolving the foundation sprites. */
609  StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, 2, layout | (edge_info << 16));
610 
611  const SpriteGroup *group = object.Resolve();
612  if (group == NULL || group->type != SGT_RESULT) return 0;
613 
614  /* Note: SpriteGroup::Resolve zeroes all registers, so register 0x100 is initialised to 0. (compatibility) */
615  return group->GetResult() + GetRegister(0x100);
616 }
617 
618 
619 uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile)
620 {
621  StationResolverObject object(statspec, st, tile, callback, param1, param2);
622  return object.ResolveCallback();
623 }
624 
635 CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_tile, const StationSpec *statspec, Axis axis, byte plat_len, byte numtracks)
636 {
637  TileIndexDiff diff = cur_tile - north_tile;
638  Slope slope = GetTileSlope(cur_tile);
639 
640  StationResolverObject object(statspec, NULL, cur_tile, CBID_STATION_LAND_SLOPE_CHECK,
641  (slope << 4) | (slope ^ (axis == AXIS_Y && HasBit(slope, CORNER_W) != HasBit(slope, CORNER_E) ? SLOPE_EW : 0)),
642  (numtracks << 24) | (plat_len << 16) | (axis == AXIS_Y ? TileX(diff) << 8 | TileY(diff) : TileY(diff) << 8 | TileX(diff)));
643  object.station_scope.axis = axis;
644 
645  uint16 cb_res = object.ResolveCallback();
646 
647  /* Failed callback means success. */
648  if (cb_res == CALLBACK_FAILED) return CommandCost();
649 
650  /* The meaning of bit 10 is inverted for a grf version < 8. */
651  if (statspec->grf_prop.grffile->grf_version < 8) ToggleBit(cb_res, 10);
652  return GetErrorMessageFromLocationCallbackResult(cb_res, statspec->grf_prop.grffile, STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
653 }
654 
655 
663 int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exec)
664 {
665  uint i;
666 
667  if (statspec == NULL || st == NULL) return 0;
668 
669  for (i = 1; i < st->num_specs && i < NUM_STATIONSSPECS_PER_STATION; i++) {
670  if (st->speclist[i].spec == NULL && st->speclist[i].grfid == 0) break;
671  }
672 
673  if (i == NUM_STATIONSSPECS_PER_STATION) {
674  /* As final effort when the spec list is already full...
675  * try to find the same spec and return that one. This might
676  * result in slightly "wrong" (as per specs) looking stations,
677  * but it's fairly unlikely that one reaches the limit anyways.
678  */
679  for (i = 1; i < st->num_specs && i < NUM_STATIONSSPECS_PER_STATION; i++) {
680  if (st->speclist[i].spec == statspec) return i;
681  }
682 
683  return -1;
684  }
685 
686  if (exec) {
687  if (i >= st->num_specs) {
688  st->num_specs = i + 1;
689  st->speclist = ReallocT(st->speclist, st->num_specs);
690 
691  if (st->num_specs == 2) {
692  /* Initial allocation */
693  st->speclist[0].spec = NULL;
694  st->speclist[0].grfid = 0;
695  st->speclist[0].localidx = 0;
696  }
697  }
698 
699  st->speclist[i].spec = statspec;
700  st->speclist[i].grfid = statspec->grf_prop.grffile->grfid;
701  st->speclist[i].localidx = statspec->grf_prop.local_id;
702 
704  }
705 
706  return i;
707 }
708 
709 
716 void DeallocateSpecFromStation(BaseStation *st, byte specindex)
717 {
718  /* specindex of 0 (default) is never freeable */
719  if (specindex == 0) return;
720 
721  ETileArea area = ETileArea(st, INVALID_TILE, TA_WHOLE);
722  /* Check all tiles over the station to check if the specindex is still in use */
723  TILE_AREA_LOOP(tile, area) {
724  if (st->TileBelongsToRailStation(tile) && GetCustomStationSpecIndex(tile) == specindex) {
725  return;
726  }
727  }
728 
729  /* This specindex is no longer in use, so deallocate it */
730  st->speclist[specindex].spec = NULL;
731  st->speclist[specindex].grfid = 0;
732  st->speclist[specindex].localidx = 0;
733 
734  /* If this was the highest spec index, reallocate */
735  if (specindex == st->num_specs - 1) {
736  for (; st->speclist[st->num_specs - 1].grfid == 0 && st->num_specs > 1; st->num_specs--) {}
737 
738  if (st->num_specs > 1) {
739  st->speclist = ReallocT(st->speclist, st->num_specs);
740  } else {
741  free(st->speclist);
742  st->num_specs = 0;
743  st->speclist = NULL;
744  st->cached_anim_triggers = 0;
745  st->cached_cargo_triggers = 0;
746  return;
747  }
748  }
749 
751 }
752 
763 bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station)
764 {
765  const DrawTileSprites *sprites = NULL;
766  const RailtypeInfo *rti = GetRailTypeInfo(railtype);
767  PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company);
768  uint tile = 2;
769 
770  const StationSpec *statspec = StationClass::Get(sclass)->GetSpec(station);
771  if (statspec == NULL) return false;
772 
774  uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, NULL, INVALID_TILE);
775  if (callback != CALLBACK_FAILED) tile = callback;
776  }
777 
778  uint32 total_offset = rti->GetRailtypeSpriteOffset();
779  uint32 relocation = 0;
780  uint32 ground_relocation = 0;
781  const NewGRFSpriteLayout *layout = NULL;
782  DrawTileSprites tmp_rail_layout;
783 
784  if (statspec->renderdata == NULL) {
785  sprites = GetStationTileLayout(STATION_RAIL, tile + axis);
786  } else {
787  layout = &statspec->renderdata[(tile < statspec->tiles) ? tile + axis : (uint)axis];
788  if (!layout->NeedsPreprocessing()) {
789  sprites = layout;
790  layout = NULL;
791  }
792  }
793 
794  if (layout != NULL) {
795  /* Sprite layout which needs preprocessing */
796  bool separate_ground = HasBit(statspec->flags, SSF_SEPARATE_GROUND);
797  uint32 var10_values = layout->PrepareLayout(total_offset, rti->fallback_railtype, 0, 0, separate_ground);
798  uint8 var10;
799  FOR_EACH_SET_BIT(var10, var10_values) {
800  uint32 var10_relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, var10);
801  layout->ProcessRegisters(var10, var10_relocation, separate_ground);
802  }
803 
804  tmp_rail_layout.seq = layout->GetLayout(&tmp_rail_layout.ground);
805  sprites = &tmp_rail_layout;
806  total_offset = 0;
807  } else {
808  /* Simple sprite layout */
809  ground_relocation = relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, 0);
811  ground_relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, 1);
812  }
813  ground_relocation += rti->fallback_railtype;
814  }
815 
816  SpriteID image = sprites->ground.sprite;
817  PaletteID pal = sprites->ground.pal;
818  RailTrackOffset overlay_offset;
819  if (rti->UsesOverlay() && SplitGroundSpriteForOverlay(NULL, &image, &overlay_offset)) {
821  DrawSprite(image, PAL_NONE, x, y);
822  DrawSprite(ground + overlay_offset, PAL_NONE, x, y);
823  } else {
824  image += HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE) ? ground_relocation : total_offset;
825  if (HasBit(pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) pal += ground_relocation;
826  DrawSprite(image, GroundSpritePaletteTransform(image, pal, palette), x, y);
827  }
828 
829  DrawRailTileSeqInGUI(x, y, sprites, total_offset, relocation, palette);
830 
831  return true;
832 }
833 
834 
835 const StationSpec *GetStationSpec(TileIndex t)
836 {
837  if (!IsCustomStationSpecIndex(t)) return NULL;
838 
839  const BaseStation *st = BaseStation::GetByTile(t);
840  uint specindex = GetCustomStationSpecIndex(t);
841  return specindex < st->num_specs ? st->speclist[specindex].spec : NULL;
842 }
843 
844 
852 {
853  const StationSpec *statspec = GetStationSpec(tile);
854 
855  return statspec != NULL && HasBit(statspec->blocked, GetStationGfx(tile));
856 }
857 
865 {
866  const StationSpec *statspec = GetStationSpec(tile);
867  uint gfx = GetStationGfx(tile);
868  /* Default stations do not draw pylons under roofs (gfx >= 4) */
869  return statspec != NULL ? HasBit(statspec->pylons, gfx) : gfx < 4;
870 }
871 
879 {
880  const StationSpec *statspec = GetStationSpec(tile);
881  return statspec == NULL || !HasBit(statspec->wires, GetStationGfx(tile));
882 }
883 
885 uint16 GetAnimStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, int extra_data)
886 {
887  return GetStationCallback(callback, param1, param2, statspec, st, tile);
888 }
889 
891 struct StationAnimationBase : public AnimationBase<StationAnimationBase, StationSpec, BaseStation, int, GetAnimStationCallback> {
892  static const CallbackID cb_animation_speed = CBID_STATION_ANIMATION_SPEED;
893  static const CallbackID cb_animation_next_frame = CBID_STATION_ANIM_NEXT_FRAME;
894 
895  static const StationCallbackMask cbm_animation_speed = CBM_STATION_ANIMATION_SPEED;
896  static const StationCallbackMask cbm_animation_next_frame = CBM_STATION_ANIMATION_NEXT_FRAME;
897 };
898 
899 void AnimateStationTile(TileIndex tile)
900 {
901  const StationSpec *ss = GetStationSpec(tile);
902  if (ss == NULL) return;
903 
905 }
906 
907 void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type)
908 {
909  /* List of coverage areas for each animation trigger */
910  static const TriggerArea tas[] = {
911  TA_TILE, TA_WHOLE, TA_WHOLE, TA_PLATFORM, TA_PLATFORM, TA_PLATFORM, TA_WHOLE
912  };
913 
914  /* Get Station if it wasn't supplied */
915  if (st == NULL) st = BaseStation::GetByTile(tile);
916 
917  /* Check the cached animation trigger bitmask to see if we need
918  * to bother with any further processing. */
919  if (!HasBit(st->cached_anim_triggers, trigger)) return;
920 
921  uint16 random_bits = Random();
922  ETileArea area = ETileArea(st, tile, tas[trigger]);
923 
924  /* Check all tiles over the station to check if the specindex is still in use */
925  TILE_AREA_LOOP(tile, area) {
926  if (st->TileBelongsToRailStation(tile)) {
927  const StationSpec *ss = GetStationSpec(tile);
928  if (ss != NULL && HasBit(ss->animation.triggers, trigger)) {
929  CargoID cargo;
930  if (cargo_type == CT_INVALID) {
931  cargo = CT_INVALID;
932  } else {
933  cargo = ss->grf_prop.grffile->cargo_map[cargo_type];
934  }
935  StationAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIM_START_STOP, ss, st, tile, (random_bits << 16) | Random(), (uint8)trigger | (cargo << 8));
936  }
937  }
938  }
939 }
940 
949 {
950  /* List of coverage areas for each animation trigger */
951  static const TriggerArea tas[] = {
952  TA_WHOLE, TA_WHOLE, TA_PLATFORM, TA_PLATFORM, TA_PLATFORM, TA_PLATFORM
953  };
954 
955  /* Get Station if it wasn't supplied */
956  if (st == NULL) st = Station::GetByTile(tile);
957 
958  /* Check the cached cargo trigger bitmask to see if we need
959  * to bother with any further processing. */
960  if (st->cached_cargo_triggers == 0) return;
961  if (cargo_type != CT_INVALID && !HasBit(st->cached_cargo_triggers, cargo_type)) return;
962 
963  uint32 whole_reseed = 0;
964  ETileArea area = ETileArea(st, tile, tas[trigger]);
965 
966  uint32 empty_mask = 0;
967  if (trigger == SRT_CARGO_TAKEN) {
968  /* Create a bitmask of completely empty cargo types to be matched */
969  for (CargoID i = 0; i < NUM_CARGO; i++) {
970  if (st->goods[i].cargo.TotalCount() == 0) {
971  SetBit(empty_mask, i);
972  }
973  }
974  }
975 
976  /* Store triggers now for var 5F */
977  SetBit(st->waiting_triggers, trigger);
978  uint32 used_triggers = 0;
979 
980  /* Check all tiles over the station to check if the specindex is still in use */
981  TILE_AREA_LOOP(tile, area) {
982  if (st->TileBelongsToRailStation(tile)) {
983  const StationSpec *ss = GetStationSpec(tile);
984  if (ss == NULL) continue;
985 
986  /* Cargo taken "will only be triggered if all of those
987  * cargo types have no more cargo waiting." */
988  if (trigger == SRT_CARGO_TAKEN) {
989  if ((ss->cargo_triggers & ~empty_mask) != 0) continue;
990  }
991 
992  if (cargo_type == CT_INVALID || HasBit(ss->cargo_triggers, cargo_type)) {
993  StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0);
994  object.waiting_triggers = st->waiting_triggers;
995 
996  const SpriteGroup *group = object.Resolve();
997  if (group == NULL) continue;
998 
999  used_triggers |= object.used_triggers;
1000 
1001  uint32 reseed = object.GetReseedSum();
1002  if (reseed != 0) {
1003  whole_reseed |= reseed;
1004  reseed >>= 16;
1005 
1006  /* Set individual tile random bits */
1007  uint8 random_bits = GetStationTileRandomBits(tile);
1008  random_bits &= ~reseed;
1009  random_bits |= Random() & reseed;
1010  SetStationTileRandomBits(tile, random_bits);
1011 
1012  MarkTileDirtyByTile(tile);
1013  }
1014  }
1015  }
1016  }
1017 
1018  /* Update whole station random bits */
1019  st->waiting_triggers &= ~used_triggers;
1020  if ((whole_reseed & 0xFFFF) != 0) {
1021  st->random_bits &= ~whole_reseed;
1022  st->random_bits |= Random() & whole_reseed;
1023  }
1024 }
1025 
1031 {
1032  st->cached_anim_triggers = 0;
1033  st->cached_cargo_triggers = 0;
1034 
1035  /* Combine animation trigger bitmask for all station specs
1036  * of this station. */
1037  for (uint i = 0; i < st->num_specs; i++) {
1038  const StationSpec *ss = st->speclist[i].spec;
1039  if (ss != NULL) {
1040  st->cached_anim_triggers |= ss->animation.triggers;
1042  }
1043  }
1044 }
1045 
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:277
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:20
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:296
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:470
void DeallocateSpecFromStation(BaseStation *st, byte specindex)
Deallocate a StationSpec from a Station.
RailType
Enumeration for all possible railtypes.
Definition: rail_type.h:29
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.
East.
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:82
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:156
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.
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:243
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 ...
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:56
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:541
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:207
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.
uint32 cargo_triggers
Bitmask of cargo types which cause trigger re-randomizing.
uint DaysInTransit() const
Returns average number of days in transit for a cargo entity.
Definition: cargopacket.h:270
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.
Northeast, upper right on your monitor.
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:25
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:20
Use a custom next frame callback.
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const
Get a variable value.
void StationUpdateCachedTriggers(BaseStation *st)
Update the cached animation trigger bitmask for a station.
Waypoint class.
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:472
static void AnimateTile(const StationSpec *spec, BaseStation *obj, TileIndex tile, bool random_animation, int extra_data=0)
Animate a single tile.
Direction
Defines the 8 directions on the map.
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:494
const DrawTileSeqStruct * seq
Array of child sprites. Terminated with a terminator entry.
Definition: sprite.h:62
Station is a waypoint (NewGRF only!)
Definition: station_type.h:74
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:116
Southeast.
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
Northeast.
Callback done for each tile of a station to check the slope.
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:136
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:115
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:379
TrackBits
Bitfield corresponding to Track.
Definition: track_type.h:41
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:3239
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:101
Struct containing information relating to NewGRF classes for stations and airports.
Definition: newgrf_class.h:21
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:343
virtual const SpriteGroup * Resolve(ResolverObject &object) const
Base sprite group resolver.
uint32 GetNewGRFVariable(const struct ResolverObject &object, byte variable, byte parameter, bool *available) const
Helper function to get a NewGRF variable that isn&#39;t implemented by the base class.
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:506
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 give tiletype.
Definition: tile_map.h:143
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.
West.
uint32 GetRandomBits() const
Get a few random bits.
static bool HasStationReservation(TileIndex t)
Get the reservation state of the rail station.
Definition: station_map.h:394
static bool IsRailStationTile(TileIndex t)
Is this tile a station tile and a rail station?
Definition: station_map.h:103
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:60
North.
Southeast.
Southwest.
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:147
#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:24
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:170
Base of waypoints.
static Axis GetRailStationAxis(TileIndex t)
Get the rail direction of a rail station.
Definition: station_map.h:338
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:18
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:113
Set when a sprite originates from an Action 1.
Definition: sprites.h:1506
StationSpecList * speclist
List of station specs of this station.
StationCallbackMask
Callback masks for stations.
Northwest.
const SpriteGroup * ResolveReal(const RealSpriteGroup *group) const
Get the real sprites of the grf.
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:126
DiagDirection
Enumeration for diagonal directions.
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
byte last_speed
Maximum speed (up to 255) of the last vehicle that tried to load this cargo.
Definition: station_base.h:246
Invalid cargo type.
Definition: cargo_type.h:70
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:42
uint32 cached_cargo_triggers
NOSAVE: Combined cargo trigger bitmask.
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:69
east and west corner are raised
Definition: slope_type.h:61
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition: landscape.cpp:509
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:139
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:561
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:39
Maximal number of cargo types in a game.
Definition: cargo_type.h:66
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:19
byte flags
Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size...
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1904
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:29
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:61
Header file for NewGRF stations.
struct BaseStation * st
Instance of the station.
StationID Source() const
Returns source of the first cargo packet in this list.
Definition: cargopacket.h:512
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:52
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:19
uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8)
Common part of station var 0x67, house var 0x62, indtile var 0x60, industry var 0x62.
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
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:190
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:217
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.
bool TileBelongsToRailStation(TileIndex tile) const
Check whether a specific tile belongs to this station.
Definition: station_base.h:494
Slope
Enumeration for the slope-type.
Definition: slope_type.h:50
uint32 GetCompanyInfo(CompanyID owner, const Livery *l)
Returns company information like in vehicle var 43 or station var 43.
A tile of a station.
Definition: tile_type.h:48
Town data structure.
Definition: town.h:55
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:351
bool CanStationTileHavePylons(TileIndex tile)
Check if a rail station tile shall have pylons when electrified.
Main group of ground images.
Definition: rail.h:42
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:284
static TileIndexDiff TileOffsByDir(Direction dir)
Convert a Direction to a TileIndexDiff.
Definition: map_func.h:357
Same as AT_LARGE.
CargoID Index() const
Determines index of this cargospec.
Definition: cargotype.h:89
uint8 localidx
Station ID within GRF of station.
uint16 local_id
id defined by the grf file for this entity
Maximum number of classes.
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:181
uint16 random_bits
Random bits assigned to this station.
StationClassID
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:114
Northwest.
StationRandomTrigger
Randomisation triggers for stations.
RailTrackOffset
Offsets for sprites within an overlay/underlay set.
Definition: rail.h:59
const struct GRFFile * grffile
grf file that introduced this entity
South.
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.
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:85
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.
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:22
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
static DiagDirection AxisToDiagDir(Axis a)
Converts an Axis to a DiagDirection.
#define TILE_ADD(x, y)
Adds to tiles together.
Definition: map_func.h:246
Flag for an invalid Axis.
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:25
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:28
Helper class for animation control.
uint16 h
The height of the area.
Definition: tilearea_type.h:21
static byte GetStationTileRandomBits(TileIndex t)
Get the random bits of a station tile.
Definition: station_map.h:518
Southwest.
Base class for all station-ish types.
Station data structure.
Definition: station_base.h:446
No track.
Definition: track_type.h:42
Axis
Allow incrementing of DiagDirDiff variables.
Set when the station accepts the cargo currently for final deliveries.
Definition: station_base.h:177
uint32 GetTriggers() const
Get the triggers.
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:833
static RailType GetRailType(TileIndex t)
Gets the rail type of the given tile.
Definition: rail_map.h:116
byte blocked
Bitmask of base tiles (0 - 7) which are blocked to trains.
uint32 grfid
GRF ID of this custom station.
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:26