cargotype.cpp

Go to the documentation of this file.
00001 /* $Id$ */
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 "cargotype.h"
00014 #include "core/bitmath_func.hpp"
00015 #include "newgrf_cargo.h"
00016 #include "strings_func.h"
00017 #include "core/sort_func.hpp"
00018 
00019 #include "table/sprites.h"
00020 #include "table/strings.h"
00021 #include "table/cargo_const.h"
00022 
00023 CargoSpec CargoSpec::array[NUM_CARGO];
00024 
00029 uint32 _cargo_mask;
00030 
00035 void SetupCargoForClimate(LandscapeID l)
00036 {
00037   assert(l < lengthof(_default_climate_cargo));
00038 
00039   /* Reset and disable all cargo types */
00040   memset(CargoSpec::array, 0, sizeof(CargoSpec::array));
00041   for (CargoID i = 0; i < lengthof(CargoSpec::array); i++) CargoSpec::Get(i)->bitnum = INVALID_CARGO;
00042 
00043   _cargo_mask = 0;
00044 
00045   for (CargoID i = 0; i < lengthof(_default_climate_cargo[l]); i++) {
00046     CargoLabel cl = _default_climate_cargo[l][i];
00047 
00048     /* Bzzt: check if cl is just an index into the cargo table */
00049     if (cl < lengthof(_default_cargo)) {
00050       /* Copy the indexed cargo */
00051       CargoSpec *cargo = CargoSpec::Get(i);
00052       *cargo = _default_cargo[cl];
00053       if (cargo->bitnum != INVALID_CARGO) SetBit(_cargo_mask, i);
00054       continue;
00055     }
00056 
00057     /* Loop through each of the default cargo types to see if
00058      * the label matches */
00059     for (uint j = 0; j < lengthof(_default_cargo); j++) {
00060       if (_default_cargo[j].label == cl) {
00061         *CargoSpec::Get(i) = _default_cargo[j];
00062 
00063         /* Populate the available cargo mask */
00064         SetBit(_cargo_mask, i);
00065         break;
00066       }
00067     }
00068   }
00069 }
00070 
00076 CargoID GetCargoIDByLabel(CargoLabel cl)
00077 {
00078   const CargoSpec *cs;
00079   FOR_ALL_CARGOSPECS(cs) {
00080     if (cs->label == cl) return cs->Index();
00081   }
00082 
00083   /* No matching label was found, so it is invalid */
00084   return CT_INVALID;
00085 }
00086 
00087 
00093 CargoID GetCargoIDByBitnum(uint8 bitnum)
00094 {
00095   if (bitnum == INVALID_CARGO) return CT_INVALID;
00096 
00097   const CargoSpec *cs;
00098   FOR_ALL_CARGOSPECS(cs) {
00099     if (cs->bitnum == bitnum) return cs->Index();
00100   }
00101 
00102   /* No matching label was found, so it is invalid */
00103   return CT_INVALID;
00104 }
00105 
00110 SpriteID CargoSpec::GetCargoIcon() const
00111 {
00112   SpriteID sprite = this->sprite;
00113   if (sprite == 0xFFFF) {
00114     /* A value of 0xFFFF indicates we should draw a custom icon */
00115     sprite = GetCustomCargoSprite(this);
00116   }
00117 
00118   if (sprite == 0) sprite = SPR_CARGO_GOODS;
00119 
00120   return sprite;
00121 }
00122 
00123 const CargoSpec *_sorted_cargo_specs[NUM_CARGO]; 
00124 uint8 _sorted_cargo_specs_size;                  
00125 uint8 _sorted_standard_cargo_specs_size;         
00126 
00127 
00129 static int CDECL CargoSpecNameSorter(const CargoSpec * const *a, const CargoSpec * const *b)
00130 {
00131   static char a_name[64];
00132   static char b_name[64];
00133 
00134   GetString(a_name, (*a)->name, lastof(a_name));
00135   GetString(b_name, (*b)->name, lastof(b_name));
00136 
00137   int res = strnatcmp(a_name, b_name); // Sort by name (natural sorting).
00138 
00139   /* If the names are equal, sort by cargo bitnum. */
00140   return (res != 0) ? res : ((*a)->bitnum - (*b)->bitnum);
00141 }
00142 
00144 static int CDECL CargoSpecClassSorter(const CargoSpec * const *a, const CargoSpec * const *b)
00145 {
00146   int res = ((*b)->classes & CC_PASSENGERS) - ((*a)->classes & CC_PASSENGERS);
00147   if (res == 0) {
00148     res = ((*b)->classes & CC_MAIL) - ((*a)->classes & CC_MAIL);
00149     if (res == 0) {
00150       res = ((*a)->classes & CC_SPECIAL) - ((*b)->classes & CC_SPECIAL);
00151       if (res == 0) {
00152         return CargoSpecNameSorter(a, b);
00153       }
00154     }
00155   }
00156 
00157   return res;
00158 }
00159 
00161 void InitializeSortedCargoSpecs()
00162 {
00163   _sorted_cargo_specs_size = 0;
00164   const CargoSpec *cargo;
00165   /* Add each cargo spec to the list. */
00166   FOR_ALL_CARGOSPECS(cargo) {
00167     _sorted_cargo_specs[_sorted_cargo_specs_size] = cargo;
00168     _sorted_cargo_specs_size++;
00169   }
00170 
00171   /* Sort cargo specifications by cargo class and name. */
00172   QSortT(_sorted_cargo_specs, _sorted_cargo_specs_size, &CargoSpecClassSorter);
00173 
00174   _sorted_standard_cargo_specs_size = 0;
00175   FOR_ALL_SORTED_CARGOSPECS(cargo) {
00176     if (cargo->classes & CC_SPECIAL) break;
00177     _sorted_standard_cargo_specs_size++;
00178   }
00179 }
00180 

Generated on Sun Jan 23 01:49:01 2011 for OpenTTD by  doxygen 1.6.1