OpenTTD Source 20241224-master-gf74b0cf984
cargoaction.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10#include "stdafx.h"
11#include "economy_base.h"
12#include "cargoaction.h"
13#include "station_base.h"
14
15#include "safeguards.h"
16
23template<class Tsource, class Tdest>
26 if (this->max_move < cp->Count()) {
27 cp = cp->Split(this->max_move);
28 this->max_move = 0;
29 } else {
30 this->max_move -= cp->Count();
31 }
32 return cp;
33}
34
41template<class Tsource>
43{
44 if (this->max_move >= cp->Count()) {
45 this->max_move -= cp->Count();
46 return cp->Count();
47 } else {
48 uint ret = this->max_move;
49 this->max_move = 0;
50 return ret;
51 }
52}
53
60template<class Tsource>
62{
63 if (remove == cp->Count()) {
64 delete cp;
65 return true;
66 } else {
67 cp->Reduce(remove);
68 return false;
69 }
70}
71
78template<>
80{
81 uint remove = this->Preprocess(cp);
82 this->source->RemoveFromCache(cp, remove);
83 return this->Postprocess(cp, remove);
84}
85
92template<>
94{
95 uint remove = this->Preprocess(cp);
96 this->source->RemoveFromMeta(cp, VehicleCargoList::MTA_KEEP, remove);
97 return this->Postprocess(cp, remove);
98}
99
107{
108 uint remove = this->Preprocess(cp);
110 this->payment->PayFinalDelivery(this->cargo, cp, remove, this->current_tile);
111 return this->Postprocess(cp, remove);
112}
113
120{
121 CargoPacket *cp_new = this->Preprocess(cp);
122 if (cp_new == nullptr) return false;
123 cp_new->UpdateLoadingTile(this->current_tile);
124 this->source->RemoveFromCache(cp_new, cp_new->Count());
126 return cp_new == cp;
127}
128
135{
136 CargoPacket *cp_new = this->Preprocess(cp);
137 if (cp_new == nullptr) return false;
138 cp_new->UpdateLoadingTile(this->current_tile);
139 this->source->reserved_count += cp_new->Count();
140 this->source->RemoveFromCache(cp_new, cp_new->Count());
142 return cp_new == cp;
143}
144
151{
152 CargoPacket *cp_new = this->Preprocess(cp);
153 if (cp_new == nullptr) cp_new = cp;
154 assert(cp_new->Count() <= this->destination->reserved_count);
155 cp_new->UpdateUnloadingTile(this->current_tile);
156 this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_LOAD, cp_new->Count());
157 this->destination->reserved_count -= cp_new->Count();
158 this->destination->Append(cp_new, this->next);
159 return cp_new == cp;
160}
161
168{
169 CargoPacket *cp_new = this->Preprocess(cp);
170 if (cp_new == nullptr) return false;
171 cp_new->UpdateUnloadingTile(this->current_tile);
173 /* No transfer credits here as they were already granted during Stage(). */
174 this->destination->Append(cp_new, cp_new->GetNextHop());
175 return cp_new == cp;
176}
177
184{
185 CargoPacket *cp_new = this->Preprocess(cp);
186 if (cp_new == nullptr) cp_new = cp;
187 this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_KEEP, cp_new->Count());
189 return cp_new == cp;
190}
191
198{
199 CargoPacket *cp_new = this->Preprocess(cp);
200 if (cp_new == nullptr) cp_new = cp;
201 StationID next = this->ge->GetVia(cp_new->GetFirstStation(), this->avoid, this->avoid2);
202 assert(next != this->avoid && next != this->avoid2);
203 if (this->source != this->destination) {
204 this->source->RemoveFromCache(cp_new, cp_new->Count());
205 this->destination->AddToCache(cp_new);
206 }
207
208 /* Legal, as insert doesn't invalidate iterators in the MultiMap, however
209 * this might insert the packet between range.first and range.second (which might be end())
210 * This is why we check for GetKey above to avoid infinite loops. */
211 this->destination->packets.Insert(next, cp_new);
212 return cp_new == cp;
213}
214
221{
222 CargoPacket *cp_new = this->Preprocess(cp);
223 if (cp_new == nullptr) cp_new = cp;
224 if (cp_new->GetNextHop() == this->avoid || cp_new->GetNextHop() == this->avoid2) {
225 cp->SetNextHop(this->ge->GetVia(cp_new->GetFirstStation(), this->avoid, this->avoid2));
226 }
227 if (this->source != this->destination) {
228 this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count());
229 this->destination->AddToMeta(cp_new, VehicleCargoList::MTA_TRANSFER);
230 }
231
232 /* Legal, as front pushing doesn't invalidate iterators in std::list. */
233 this->destination->packets.push_front(cp_new);
234 return cp_new == cp;
235}
236
239template bool CargoRemoval<VehicleCargoList>::Postprocess(CargoPacket *cp, uint remove);
240template bool CargoRemoval<StationCargoList>::Postprocess(CargoPacket *cp, uint remove);
Actions to be applied to cargo packets.
CargoPayment * payment
Payment object where payments will be registered.
Definition cargoaction.h:42
TileIndex current_tile
Current tile cargo delivery is happening.
Definition cargoaction.h:41
bool operator()(CargoPacket *cp)
Delivers some cargo.
CargoID cargo
The cargo type of the cargo.
Definition cargoaction.h:43
@ MTA_KEEP
Keep the cargo in the vehicle.
@ MTA_DELIVER
Deliver the cargo to some town or industry.
@ MTA_LOAD
Load the cargo from the station.
@ MTA_TRANSFER
Transfer the cargo to the station.
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
bool operator()(CargoPacket *cp)
Loads some cargo onto a vehicle.
TileIndex current_tile
Current tile cargo loading is happening.
Definition cargoaction.h:85
StationCargoList * source
Source of the cargo.
Definition cargoaction.h:58
CargoPacket * Preprocess(CargoPacket *cp)
Decides if a packet needs to be split.
VehicleCargoList * destination
Destination for the cargo.
Definition cargoaction.h:59
Abstract action of removing cargo from a vehicle or a station.
Definition cargoaction.h:20
uint Preprocess(CargoPacket *cp)
Determines the amount of cargo to be removed from a packet and removes that from the metadata of the ...
bool Postprocess(CargoPacket *cp, uint remove)
Finalize cargo removal.
VehicleCargoList * source
Source of the cargo.
Definition cargoaction.h:22
bool operator()(CargoPacket *cp)
Reserves some cargo for loading.
TileIndex current_tile
Current tile cargo unloading is happening.
bool operator()(CargoPacket *cp)
Returns some reserved cargo.
bool operator()(CargoPacket *cp)
Shifts some cargo from a vehicle to another one.
bool operator()(CargoPacket *cp)
Transfers some cargo from a vehicle to a station.
TileIndex current_tile
Current tile cargo unloading is happening.
Definition cargoaction.h:75
void Append(CargoPacket *cp, StationID next)
Appends the given cargo packet to the range of packets with the same next station.
uint reserved_count
Amount of cargo being reserved for loading.
bool operator()(CargoPacket *cp)
Reroutes some cargo from one Station sublist to another.
void RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count)
Removes a packet or part of it from the metadata.
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
bool operator()(CargoPacket *cp)
Reroutes some cargo in a VehicleCargoList.
Base classes related to the economy.
A number of safeguards to prevent using unsafe methods.
Base classes/functions for stations.
@ Count
by amount of cargo
Definition of base types and functions in a cross-platform compatible way.
Container for cargo from the same location and time.
Definition cargopacket.h:40
void Reduce(uint count)
Reduce the packet by the given amount and remove the feeder share.
uint16_t Count() const
Gets the number of 'items' in this packet.
void SetNextHop(StationID next_hop)
Sets the station where the packet is supposed to go next.
Definition cargopacket.h:92
CargoPacket * Split(uint new_size)
Split this packet in two and return the split off part.
void UpdateLoadingTile(TileIndex tile)
Update for the cargo being loaded on this tile.
StationID GetNextHop() const
Gets the ID of station the cargo wants to go next.
StationID GetFirstStation() const
Gets the ID of the station where the cargo was loaded for the first time.
void UpdateUnloadingTile(TileIndex tile)
Update for the cargo being unloaded on this tile.
void PayFinalDelivery(CargoID cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
Handle payment for final delivery of the given cargo packet.
Definition economy.cpp:1236
StationID GetVia(StationID source) const
Get the best next hop for a cargo packet from station source.