diff options
author | alberth <alberth@openttd.org> | 2012-07-15 17:05:17 +0000 |
---|---|---|
committer | alberth <alberth@openttd.org> | 2012-07-15 17:05:17 +0000 |
commit | 1d11291071d41712b61983f195f1ba21d9c7ebcb (patch) | |
tree | 90cad3481e2c441d9bd01d7b8e78787c0b11705a /src/cargomonitor.cpp | |
parent | 6821f5cd22bb312ff8b51c08ba67d5fc615c80fc (diff) | |
download | openttd-1d11291071d41712b61983f195f1ba21d9c7ebcb.tar.xz |
(svn r24404) -Add: Data structures for cargo transport monitoring.
Diffstat (limited to 'src/cargomonitor.cpp')
-rw-r--r-- | src/cargomonitor.cpp | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/cargomonitor.cpp b/src/cargomonitor.cpp new file mode 100644 index 000000000..be808fd8e --- /dev/null +++ b/src/cargomonitor.cpp @@ -0,0 +1,125 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * 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. + * 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. + * 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/>. + */ + +/** @file cargomonitor.cpp Implementation of the cargo transport monitoring. */ + +#include "stdafx.h" +#include "cargomonitor.h" +#include "station_base.h" + +CargoMonitorMap _cargo_pickups; ///< Map of monitored pick-ups to the amount since last query/activation. +CargoMonitorMap _cargo_deliveries; ///< Map of monitored deliveries to the amount since last query/activation. + +/** Clear all pick-up cargo monitors. */ +void ClearCargoPickupMonitoring() +{ + _cargo_pickups.clear(); +} + +/** Clear all delivery cargo monitors. */ +void ClearCargoDeliveryMonitoring() +{ + _cargo_deliveries.clear(); +} + +/** + * Get and reset the amount associated with a cargo monitor. + * @param[in,out] monitor_map Monitoring map to search (and reset for the queried entry). + * @oaram monitor Cargo monitor to query/reset. + * @param keep_monitoring After returning from this call, continue monitoring. + * @return Amount collected since last query/activation for the monitored combination. + */ +static uint32 GetAmount(CargoMonitorMap &monitor_map, CargoMonitorID monitor, bool keep_monitoring) +{ + CargoMonitorMap::iterator iter = monitor_map.find(monitor); + if (iter == monitor_map.end()) { + if (keep_monitoring) { + std::pair<CargoMonitorID, uint32> p(monitor, 0); + monitor_map.insert(p); + } + return 0; + } else { + uint32 result = iter->second; + iter->second = 0; + if (!keep_monitoring) monitor_map.erase(iter); + return result; + } +} + +/** + * Get the amount of cargo delivered for the given cargo monitor since activation or last query. + * @param monitor Cargo monitor to query. + * @param keep_monitoring After returning from this call, continue monitoring. + * @return Amount of delivered cargo for the monitored combination. + */ +uint32 GetDeliveryAmount(CargoMonitorID monitor, bool keep_monitoring) +{ + return GetAmount(_cargo_deliveries, monitor, keep_monitoring); +} + +/** + * Get the amount of cargo picked up for the given cargo monitor since activation or last query. + * @param monitor Monitoring number to query. + * @param keep_monitoring After returning from this call, continue monitoring. + * @return Amount of picked up cargo for the monitored combination. + * @note Cargo pick up is counted on final delivery, to prevent users getting credit for picking up cargo without delivering it. + */ +uint32 GetPickupAmount(CargoMonitorID monitor, bool keep_monitoring) +{ + return GetAmount(_cargo_pickups, monitor, keep_monitoring); +} + +/** + * Cargo was delivered to its final destination, update the pickup and delivery maps. + * @param cargo_type type of cargo. + * @param company company delivering the cargo. + * @param amount Amount of cargo delivered. + * @param src_type type of \a src. + * @param src index of source. + * @param st station where the cargo is delivered to. + */ +void AddCargoDelivery(CargoID cargo_type, CompanyID company, uint32 amount, SourceType src_type, SourceID src, const Station *st) +{ + if (amount == 0) return; + + if (src != INVALID_SOURCE) { + /* Handle pickup update. */ + switch (src_type) { + case ST_INDUSTRY: { + CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, src); + CargoMonitorMap::iterator iter = _cargo_pickups.find(num); + if (iter != _cargo_pickups.end()) iter->second += amount; + break; + } + case ST_TOWN: { + CargoMonitorID num = EncodeCargoTownMonitor(company, cargo_type, src); + CargoMonitorMap::iterator iter = _cargo_pickups.find(num); + if (iter != _cargo_pickups.end()) iter->second += amount; + break; + } + default: break; + } + } + + /* Handle delivery. + * Note that delivery in the right area is sufficient to prevent trouble with neighbouring industries or houses. */ + + /* Town delivery. */ + CargoMonitorID num = EncodeCargoTownMonitor(company, cargo_type, st->town->index); + CargoMonitorMap::iterator iter = _cargo_deliveries.find(num); + if (iter != _cargo_deliveries.end()) iter->second += amount; + + /* Industry delivery. */ + for (const Industry * const *ip = st->industries_near.Begin(); ip != st->industries_near.End(); ip++) { + CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, (*ip)->index); + CargoMonitorMap::iterator iter = _cargo_deliveries.find(num); + if (iter != _cargo_deliveries.end()) iter->second += amount; + } +} + |