Files
@ r28486:aff297ed5a05
Branch filter:
Location: cpp/openttd-patchpack/source/src/cargomonitor.cpp
r28486:aff297ed5a05
6.0 KiB
text/x-c
Codechange: Allow constexpr NWidgetPart construction.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | /*
* 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"
#include "safeguards.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.
/**
* Helper method for #ClearCargoPickupMonitoring and #ClearCargoDeliveryMonitoring.
* Clears all monitors that belong to the specified company or all if #INVALID_OWNER
* is specified as company.
* @param cargo_monitor_map reference to the cargo monitor map to operate on.
* @param company company to clear cargo monitors for or #INVALID_OWNER if all cargo monitors should be cleared.
*/
static void ClearCargoMonitoring(CargoMonitorMap &cargo_monitor_map, CompanyID company = INVALID_OWNER)
{
if (company == INVALID_OWNER) {
cargo_monitor_map.clear();
return;
}
for (auto it = cargo_monitor_map.begin(); it != cargo_monitor_map.end(); /* nothing */) {
if (DecodeMonitorCompany(it->first) == company) {
it = cargo_monitor_map.erase(it);
} else {
++it;
}
}
}
/**
* Clear all pick-up cargo monitors.
* @param company clear all pick-up monitors for this company or if #INVALID_OWNER
* is passed, all pick-up monitors are cleared regardless of company.
*/
void ClearCargoPickupMonitoring(CompanyID company)
{
ClearCargoMonitoring(_cargo_pickups, company);
}
/**
* Clear all delivery cargo monitors.
* @param company clear all delivery monitors for this company or if #INVALID_OWNER
* is passed, all delivery monitors are cleared regardless of company.
*/
void ClearCargoDeliveryMonitoring(CompanyID company)
{
ClearCargoMonitoring(_cargo_deliveries, company);
}
/**
* 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).
* @param 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 int32_t 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_t> p(monitor, 0);
monitor_map.insert(p);
}
return 0;
} else {
int32_t 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.
*/
int32_t 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.
*/
int32_t 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.
* @param dest industry index where the cargo is delivered to.
*/
void AddCargoDelivery(CargoID cargo_type, CompanyID company, uint32_t amount, SourceType src_type, SourceID src, const Station *st, IndustryID dest)
{
if (amount == 0) return;
if (src != INVALID_SOURCE) {
/* Handle pickup update. */
switch (src_type) {
case SourceType::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 SourceType::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 auto &i : st->industries_near) {
if (i.industry->index != dest) continue;
CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, i.industry->index);
CargoMonitorMap::iterator iter = _cargo_deliveries.find(num);
if (iter != _cargo_deliveries.end()) iter->second += amount;
}
}
|