Files
@ r25553:92872b4fd6f6
Branch filter:
Location: cpp/openttd-patchpack/source/src/cargomonitor.cpp
r25553:92872b4fd6f6
6.0 KiB
text/x-c
Fix #9281: acquire a company uses special bookkeeping to make you rich (#9300)
When you buy-out a company, you got your shares back. This is
based on company-value, which includes values for the vehicles etc.
In other words, you not only got the vehicles, but you also got
paid to get them back.
Additionally, you also got the loan of the company, but not the
money for the loan (as that is subtracted from the company-value).
Solve this by changing the rules of a buy-out: don't sell your
shares, get the loan AND the balance and get the infrastructure.
When you buy-out a company, you got your shares back. This is
based on company-value, which includes values for the vehicles etc.
In other words, you not only got the vehicles, but you also got
paid to get them back.
Additionally, you also got the loan of the company, but not the
money for the loan (as that is subtracted from the company-value).
Solve this by changing the rules of a buy-out: don't sell your
shares, get the loan AND the balance and get the infrastructure.
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 159 | /*
* 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;
}
CargoMonitorMap::iterator next;
for (CargoMonitorMap::iterator it = cargo_monitor_map.begin(); it != cargo_monitor_map.end(); it = next) {
next = it;
next++;
if (DecodeMonitorCompany(it->first) == company) {
cargo_monitor_map.erase(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 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 {
int32 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 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 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 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 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 (Industry *ind : st->industries_near) {
if (ind->index != dest) continue;
CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, ind->index);
CargoMonitorMap::iterator iter = _cargo_deliveries.find(num);
if (iter != _cargo_deliveries.end()) iter->second += amount;
}
}
|