vehiclelist.cpp

Go to the documentation of this file.
00001 /* $Id: vehiclelist.cpp 25959 2013-11-09 06:52:08Z rubidium $ */
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 "train.h"
00014 #include "vehiclelist.h"
00015 
00020 uint32 VehicleListIdentifier::Pack()
00021 {
00022   byte c = this->company == OWNER_NONE ? 0xF : (byte)this->company;
00023   assert(c             < (1 <<  4));
00024   assert(this->vtype   < (1 <<  2));
00025   assert(this->index   < (1 << 20));
00026   assert(this->type    < VLT_END);
00027   assert_compile(VLT_END <= (1 <<  3));
00028 
00029   return c << 28 | this->type << 23 | this->vtype << 26 | this->index;
00030 }
00031 
00037 bool VehicleListIdentifier::Unpack(uint32 data)
00038 {
00039   byte c        = GB(data, 28, 4);
00040   this->company = c == 0xF ? OWNER_NONE : (CompanyID)c;
00041   this->type    = (VehicleListType)GB(data, 23, 3);
00042   this->vtype   = (VehicleType)GB(data, 26, 2);
00043   this->index   = GB(data, 0, 20);
00044 
00045   return this->type < VLT_END;
00046 }
00047 
00052 VehicleListIdentifier::VehicleListIdentifier(uint32 data)
00053 {
00054   bool ret = this->Unpack(data);
00055   assert(ret);
00056 }
00057 
00066 void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engines, VehicleList *wagons, bool individual_wagons)
00067 {
00068   engines->Clear();
00069   if (wagons != NULL && wagons != engines) wagons->Clear();
00070 
00071   const Vehicle *v;
00072   FOR_ALL_VEHICLES(v) {
00073     /* General tests for all vehicle types */
00074     if (v->type != type) continue;
00075     if (v->tile != tile) continue;
00076 
00077     switch (type) {
00078       case VEH_TRAIN: {
00079         const Train *t = Train::From(v);
00080         if (t->IsArticulatedPart() || t->IsRearDualheaded()) continue;
00081         if (t->track != TRACK_BIT_DEPOT) continue;
00082         if (wagons != NULL && t->First()->IsFreeWagon()) {
00083           if (individual_wagons || t->IsFreeWagon()) *wagons->Append() = t;
00084           continue;
00085         }
00086         break;
00087       }
00088 
00089       default:
00090         if (!v->IsInDepot()) continue;
00091         break;
00092     }
00093 
00094     if (!v->IsPrimaryVehicle()) continue;
00095 
00096     *engines->Append() = v;
00097   }
00098 
00099   /* Ensure the lists are not wasting too much space. If the lists are fresh
00100    * (i.e. built within a command) then this will actually do nothing. */
00101   engines->Compact();
00102   if (wagons != NULL && wagons != engines) wagons->Compact();
00103 }
00104 
00111 bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli)
00112 {
00113   list->Clear();
00114 
00115   const Vehicle *v;
00116 
00117   switch (vli.type) {
00118     case VL_STATION_LIST:
00119       FOR_ALL_VEHICLES(v) {
00120         if (v->type == vli.vtype && v->IsPrimaryVehicle()) {
00121           const Order *order;
00122 
00123           FOR_VEHICLE_ORDERS(v, order) {
00124             if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT) || order->IsType(OT_IMPLICIT))
00125                 && order->GetDestination() == vli.index) {
00126               *list->Append() = v;
00127               break;
00128             }
00129           }
00130         }
00131       }
00132       break;
00133 
00134     case VL_SHARED_ORDERS:
00135       /* Add all vehicles from this vehicle's shared order list */
00136       v = Vehicle::GetIfValid(vli.index);
00137       if (v == NULL || v->type != vli.vtype || !v->IsPrimaryVehicle()) return false;
00138 
00139       for (; v != NULL; v = v->NextShared()) {
00140         *list->Append() = v;
00141       }
00142       break;
00143 
00144     case VL_GROUP_LIST:
00145       if (vli.index != ALL_GROUP) {
00146         FOR_ALL_VEHICLES(v) {
00147           if (v->type == vli.vtype && v->IsPrimaryVehicle() &&
00148               v->owner == vli.company && v->group_id == vli.index) {
00149             *list->Append() = v;
00150           }
00151         }
00152         break;
00153       }
00154       /* FALL THROUGH */
00155 
00156     case VL_STANDARD:
00157       FOR_ALL_VEHICLES(v) {
00158         if (v->type == vli.vtype && v->owner == vli.company && v->IsPrimaryVehicle()) {
00159           *list->Append() = v;
00160         }
00161       }
00162       break;
00163 
00164     case VL_DEPOT_LIST:
00165       FOR_ALL_VEHICLES(v) {
00166         if (v->type == vli.vtype && v->IsPrimaryVehicle()) {
00167           const Order *order;
00168 
00169           FOR_VEHICLE_ORDERS(v, order) {
00170             if (order->IsType(OT_GOTO_DEPOT) && !(order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) && order->GetDestination() == vli.index) {
00171               *list->Append() = v;
00172               break;
00173             }
00174           }
00175         }
00176       }
00177       break;
00178 
00179     default: return false;
00180   }
00181 
00182   list->Compact();
00183   return true;
00184 }