# newgrf_railtype.cpp

Go to the documentation of this file.

    00001 /* $Id: newgrf_railtype.cpp 26388 2014-03-03 20:02:31Z 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
    00089 RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1, uint32 param2)
    00090   : ResolverObject(rti != NULL ? rti->grffile[rtsg] : NULL, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, tile, context)
    00091 {
    00092   this->root_spritegroup = rti != NULL ? rti->group[rtsg] : NULL;
    00093 }
    00094
    00103 SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context)
    00104 {
    00105   assert(rtsg < RTSG_END);
    00106
    00107   if (rti->group[rtsg] == NULL) return 0;
    00108
    00109   RailTypeResolverObject object(rti, tile, context, rtsg);
    00110   const SpriteGroup *group = object.Resolve();
    00111   if (group == NULL || group->GetNumResults() == 0) return 0;
    00112
    00113   return group->GetResult();
    00114 }
    00115
    00126 SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui)
    00127 {
    00128   if (rti->group[RTSG_SIGNALS] == NULL) return 0;
    00129
    00130   uint32 param1 = gui ? 0x10 : 0x00;
    00131   uint32 param2 = (type << 16) | (var << 8) | state;
    00132   RailTypeResolverObject object(rti, tile, TCX_NORMAL, RTSG_SIGNALS, param1, param2);
    00133
    00134   const SpriteGroup *group = object.Resolve();
    00135   if (group == NULL || group->GetNumResults() == 0) return 0;
    00136
    00137   return group->GetResult();
    00138 }
    00139
    00146 uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile)
    00147 {
    00148   /* No rail type table present, return rail type as-is */
    00149   if (grffile == NULL || grffile->railtype_list.Length() == 0) return railtype;
    00150
    00151   /* Look for a matching rail type label in the table */
    00152   RailTypeLabel label = GetRailTypeInfo(railtype)->label;
    00153   int index = grffile->railtype_list.FindIndex(label);
    00154   if (index >= 0) return index;
    00155
    00156   /* If not found, return as invalid */
    00157   return 0xFF;
    00158 }