cargomonitor.cpp

Go to the documentation of this file.
00001 /* $Id: cargomonitor.cpp 26714 2014-08-03 14:03:07Z 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 "cargomonitor.h"
00014 #include "station_base.h"
00015 
00016 CargoMonitorMap _cargo_pickups;    
00017 CargoMonitorMap _cargo_deliveries; 
00018 
00026 static void ClearCargoMonitoring(CargoMonitorMap &cargo_monitor_map, CompanyID company = INVALID_OWNER)
00027 {
00028   if (company == INVALID_OWNER) {
00029     cargo_monitor_map.clear();
00030     return;
00031   }
00032 
00033   CargoMonitorMap::iterator next;
00034   for (CargoMonitorMap::iterator it = cargo_monitor_map.begin(); it != cargo_monitor_map.end(); it = next) {
00035     next = it;
00036     next++;
00037     if (DecodeMonitorCompany(it->first) == company) {
00038       cargo_monitor_map.erase(it);
00039     }
00040   }
00041 }
00042 
00048 void ClearCargoPickupMonitoring(CompanyID company)
00049 {
00050   ClearCargoMonitoring(_cargo_pickups, company);
00051 }
00052 
00058 void ClearCargoDeliveryMonitoring(CompanyID company)
00059 {
00060   ClearCargoMonitoring(_cargo_deliveries, company);
00061 }
00062 
00070 static int32 GetAmount(CargoMonitorMap &monitor_map, CargoMonitorID monitor, bool keep_monitoring)
00071 {
00072   CargoMonitorMap::iterator iter = monitor_map.find(monitor);
00073   if (iter == monitor_map.end()) {
00074     if (keep_monitoring) {
00075       std::pair<CargoMonitorID, uint32> p(monitor, 0);
00076       monitor_map.insert(p);
00077     }
00078     return 0;
00079   } else {
00080     int32 result = iter->second;
00081     iter->second = 0;
00082     if (!keep_monitoring) monitor_map.erase(iter);
00083     return result;
00084   }
00085 }
00086 
00093 int32 GetDeliveryAmount(CargoMonitorID monitor, bool keep_monitoring)
00094 {
00095   return GetAmount(_cargo_deliveries, monitor, keep_monitoring);
00096 }
00097 
00105 int32 GetPickupAmount(CargoMonitorID monitor, bool keep_monitoring)
00106 {
00107   return GetAmount(_cargo_pickups, monitor, keep_monitoring);
00108 }
00109 
00119 void AddCargoDelivery(CargoID cargo_type, CompanyID company, uint32 amount, SourceType src_type, SourceID src, const Station *st)
00120 {
00121   if (amount == 0) return;
00122 
00123   if (src != INVALID_SOURCE) {
00124     /* Handle pickup update. */
00125     switch (src_type) {
00126       case ST_INDUSTRY: {
00127         CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, src);
00128         CargoMonitorMap::iterator iter = _cargo_pickups.find(num);
00129         if (iter != _cargo_pickups.end()) iter->second += amount;
00130         break;
00131       }
00132       case ST_TOWN: {
00133         CargoMonitorID num = EncodeCargoTownMonitor(company, cargo_type, src);
00134         CargoMonitorMap::iterator iter = _cargo_pickups.find(num);
00135         if (iter != _cargo_pickups.end()) iter->second += amount;
00136         break;
00137       }
00138       default: break;
00139     }
00140   }
00141 
00142   /* Handle delivery.
00143    * Note that delivery in the right area is sufficient to prevent trouble with neighbouring industries or houses. */
00144 
00145   /* Town delivery. */
00146   CargoMonitorID num = EncodeCargoTownMonitor(company, cargo_type, st->town->index);
00147   CargoMonitorMap::iterator iter = _cargo_deliveries.find(num);
00148   if (iter != _cargo_deliveries.end()) iter->second += amount;
00149 
00150   /* Industry delivery. */
00151   for (const Industry * const *ip = st->industries_near.Begin(); ip != st->industries_near.End(); ip++) {
00152     CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, (*ip)->index);
00153     CargoMonitorMap::iterator iter = _cargo_deliveries.find(num);
00154     if (iter != _cargo_deliveries.end()) iter->second += amount;
00155   }
00156 }
00157