OpenTTD
newgrf_railtype.cpp
Go to the documentation of this file.
1 /* $Id: newgrf_railtype.cpp 27342 2015-07-26 12:25:37Z 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 "newgrf_railtype.h"
15 #include "date_func.h"
16 #include "depot_base.h"
17 #include "town.h"
18 
19 #include "safeguards.h"
20 
21 /* virtual */ uint32 RailTypeScopeResolver::GetRandomBits() const
22 {
23  uint tmp = CountBits(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE);
24  return GB(tmp, 0, 2);
25 }
26 
27 /* virtual */ uint32 RailTypeScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
28 {
29  if (this->tile == INVALID_TILE) {
30  switch (variable) {
31  case 0x40: return 0;
32  case 0x41: return 0;
33  case 0x42: return 0;
34  case 0x43: return _date;
35  case 0x44: return HZB_TOWN_EDGE;
36  }
37  }
38 
39  switch (variable) {
40  case 0x40: return GetTerrainType(this->tile, this->context);
41  case 0x41: return 0;
42  case 0x42: return IsLevelCrossingTile(this->tile) && IsCrossingBarred(this->tile);
43  case 0x43:
44  if (IsRailDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date;
45  return _date;
46  case 0x44: {
47  const Town *t = NULL;
48  if (IsRailDepotTile(this->tile)) {
49  t = Depot::GetByTile(this->tile)->town;
50  } else if (IsLevelCrossingTile(this->tile)) {
51  t = ClosestTownFromTile(this->tile, UINT_MAX);
52  }
53  return t != NULL ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE;
54  }
55  }
56 
57  DEBUG(grf, 1, "Unhandled rail type tile variable 0x%X", variable);
58 
59  *available = false;
60  return UINT_MAX;
61 }
62 
63 /* virtual */ const SpriteGroup *RailTypeResolverObject::ResolveReal(const RealSpriteGroup *group) const
64 {
65  if (group->num_loading > 0) return group->loading[0];
66  if (group->num_loaded > 0) return group->loaded[0];
67  return NULL;
68 }
69 
77 {
78  this->tile = tile;
79  this->context = context;
80 }
81 
91 RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1, uint32 param2)
92  : ResolverObject(rti != NULL ? rti->grffile[rtsg] : NULL, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, tile, context)
93 {
94  this->root_spritegroup = rti != NULL ? rti->group[rtsg] : NULL;
95 }
96 
106 SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context, uint *num_results)
107 {
108  assert(rtsg < RTSG_END);
109 
110  if (rti->group[rtsg] == NULL) return 0;
111 
112  RailTypeResolverObject object(rti, tile, context, rtsg);
113  const SpriteGroup *group = object.Resolve();
114  if (group == NULL || group->GetNumResults() == 0) return 0;
115 
116  if (num_results) *num_results = group->GetNumResults();
117 
118  return group->GetResult();
119 }
120 
132 {
133  if (rti->group[RTSG_SIGNALS] == NULL) return 0;
134 
135  uint32 param1 = gui ? 0x10 : 0x00;
136  uint32 param2 = (type << 16) | (var << 8) | state;
137  RailTypeResolverObject object(rti, tile, TCX_NORMAL, RTSG_SIGNALS, param1, param2);
138 
139  const SpriteGroup *group = object.Resolve();
140  if (group == NULL || group->GetNumResults() == 0) return 0;
141 
142  return group->GetResult();
143 }
144 
151 uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile)
152 {
153  /* No rail type table present, return rail type as-is */
154  if (grffile == NULL || grffile->railtype_list.Length() == 0) return railtype;
155 
156  /* Look for a matching rail type label in the table */
157  RailTypeLabel label = GetRailTypeInfo(railtype)->label;
158  int index = grffile->railtype_list.FindIndex(label);
159  if (index >= 0) return index;
160 
161  /* If not found, return as invalid */
162  return 0xFF;
163 }