newgrf_railtype.cpp

Go to the documentation of this file.
00001 /* $Id: newgrf_railtype.cpp 26085 2013-11-24 14:41:19Z frosch $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "stdafx.h"
00013 #include "debug.h"
00014 #include "newgrf_railtype.h"
00015 #include "date_func.h"
00016 #include "depot_base.h"
00017 #include "town.h"
00018 
00019 /* virtual */ uint32 RailTypeScopeResolver::GetRandomBits() const
00020 {
00021   uint tmp = CountBits(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE);
00022   return GB(tmp, 0, 2);
00023 }
00024 
00025 /* virtual */ uint32 RailTypeScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
00026 {
00027   if (this->tile == INVALID_TILE) {
00028     switch (variable) {
00029       case 0x40: return 0;
00030       case 0x41: return 0;
00031       case 0x42: return 0;
00032       case 0x43: return _date;
00033       case 0x44: return HZB_TOWN_EDGE;
00034     }
00035   }
00036 
00037   switch (variable) {
00038     case 0x40: return GetTerrainType(this->tile, this->context);
00039     case 0x41: return 0;
00040     case 0x42: return IsLevelCrossingTile(this->tile) && IsCrossingBarred(this->tile);
00041     case 0x43:
00042       if (IsRailDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date;
00043       return _date;
00044     case 0x44: {
00045       const Town *t = NULL;
00046       if (IsRailDepotTile(this->tile)) {
00047         t = Depot::GetByTile(this->tile)->town;
00048       } else if (IsLevelCrossingTile(this->tile)) {
00049         t = ClosestTownFromTile(this->tile, UINT_MAX);
00050       }
00051       return t != NULL ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE;
00052     }
00053   }
00054 
00055   DEBUG(grf, 1, "Unhandled rail type tile variable 0x%X", variable);
00056 
00057   *available = false;
00058   return UINT_MAX;
00059 }
00060 
00061 /* virtual */ const SpriteGroup *RailTypeResolverObject::ResolveReal(const RealSpriteGroup *group) const
00062 {
00063   if (group->num_loading > 0) return group->loading[0];
00064   if (group->num_loaded  > 0) return group->loaded[0];
00065   return NULL;
00066 }
00067 
00074 RailTypeScopeResolver::RailTypeScopeResolver(ResolverObject &ro, TileIndex tile, TileContext context) : ScopeResolver(ro)
00075 {
00076   this->tile = tile;
00077   this->context = context;
00078 }
00079 
00088 RailTypeResolverObject::RailTypeResolverObject(TileIndex tile, TileContext context, const GRFFile *grffile, uint32 param1, uint32 param2)
00089   : ResolverObject(grffile, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, tile, context)
00090 {
00091 }
00092 
00101 SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context)
00102 {
00103   assert(rtsg < RTSG_END);
00104 
00105   if (rti->group[rtsg] == NULL) return 0;
00106 
00107   RailTypeResolverObject object(tile, context, rti->grffile[rtsg]);
00108   const SpriteGroup *group = SpriteGroup::Resolve(rti->group[rtsg], object);
00109   if (group == NULL || group->GetNumResults() == 0) return 0;
00110 
00111   return group->GetResult();
00112 }
00113 
00124 SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui)
00125 {
00126   if (rti->group[RTSG_SIGNALS] == NULL) return 0;
00127 
00128   uint32 param1 = gui ? 0x10 : 0x00;
00129   uint32 param2 = (type << 16) | (var << 8) | state;
00130   RailTypeResolverObject object(tile, TCX_NORMAL, rti->grffile[RTSG_SIGNALS], param1, param2);
00131 
00132   const SpriteGroup *group = SpriteGroup::Resolve(rti->group[RTSG_SIGNALS], object);
00133   if (group == NULL || group->GetNumResults() == 0) return 0;
00134 
00135   return group->GetResult();
00136 }
00137 
00144 uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile)
00145 {
00146   /* No rail type table present, return rail type as-is */
00147   if (grffile == NULL || grffile->railtype_list.Length() == 0) return railtype;
00148 
00149   /* Look for a matching rail type label in the table */
00150   RailTypeLabel label = GetRailTypeInfo(railtype)->label;
00151   int index = grffile->railtype_list.FindIndex(label);
00152   if (index >= 0) return index;
00153 
00154   /* If not found, return as invalid */
00155   return 0xFF;
00156 }