# vehiclelist.cpp

Go to the documentation of this file.

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