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 
8 /** @file cargoaction.h Actions to be applied to cargo packets. */
9 
10 #ifndef CARGOACTION_H
11 #define CARGOACTION_H
12 
13 #include "cargopacket.h"
14 
15 /**
16  * Abstract action of removing cargo from a vehicle or a station.
17  * @tparam Tsource CargoList subclass to remove cargo from.
18  */
19 template<class Tsource>
20 class CargoRemoval {
21 protected:
22 	Tsource *source; ///< Source of the cargo.
23 	uint max_move;   ///< Maximum amount of cargo to be removed with this action.
24 	uint Preprocess(CargoPacket *cp);
25 	bool Postprocess(CargoPacket *cp, uint remove);
26 public:
CargoRemoval(Tsource * source,uint max_move)27 	CargoRemoval(Tsource *source, uint max_move) : source(source), max_move(max_move) {}
28 
29 	/**
30 	 * Returns how much more cargo can be removed with this action.
31 	 * @return Amount of cargo this action can still remove.
32 	 */
MaxMove()33 	uint MaxMove() { return this->max_move; }
34 
35 	bool operator()(CargoPacket *cp);
36 };
37 
38 /** Action of final delivery of cargo. */
39 class CargoDelivery : public CargoRemoval<VehicleCargoList> {
40 protected:
41 	CargoPayment *payment; ///< Payment object where payments will be registered.
42 public:
CargoDelivery(VehicleCargoList * source,uint max_move,CargoPayment * payment)43 	CargoDelivery(VehicleCargoList *source, uint max_move, CargoPayment *payment) :
44 			CargoRemoval<VehicleCargoList>(source, max_move), payment(payment) {}
45 	bool operator()(CargoPacket *cp);
46 };
47 
48 /**
49  * Abstract action for moving cargo from one list to another.
50  * @tparam Tsource CargoList subclass to remove cargo from.
51  * @tparam Tdest CargoList subclass to add cargo to.
52  */
53 template<class Tsource, class Tdest>
54 class CargoMovement {
55 protected:
56 	Tsource *source;    ///< Source of the cargo.
57 	Tdest *destination; ///< Destination for the cargo.
58 	uint max_move;      ///< Maximum amount of cargo to be moved with this action.
59 	CargoPacket *Preprocess(CargoPacket *cp);
60 public:
CargoMovement(Tsource * source,Tdest * destination,uint max_move)61 	CargoMovement(Tsource *source, Tdest *destination, uint max_move) : source(source), destination(destination), max_move(max_move) {}
62 
63 	/**
64 	 * Returns how much more cargo can be moved with this action.
65 	 * @return Amount of cargo this action can still move.
66 	 */
MaxMove()67 	uint MaxMove() { return this->max_move; }
68 };
69 
70 /** Action of transferring cargo from a vehicle to a station. */
71 class CargoTransfer : public CargoMovement<VehicleCargoList, StationCargoList> {
72 public:
CargoTransfer(VehicleCargoList * source,StationCargoList * destination,uint max_move)73 	CargoTransfer(VehicleCargoList *source, StationCargoList *destination, uint max_move) :
74 			CargoMovement<VehicleCargoList, StationCargoList>(source, destination, max_move) {}
75 	bool operator()(CargoPacket *cp);
76 };
77 
78 /** Action of loading cargo from a station onto a vehicle. */
79 class CargoLoad : public CargoMovement<StationCargoList, VehicleCargoList> {
80 protected:
81 	TileIndex load_place; ///< TileIndex to be saved in the packets' loaded_at_xy.
82 public:
CargoLoad(StationCargoList * source,VehicleCargoList * destination,uint max_move,TileIndex load_place)83 	CargoLoad(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex load_place) :
84 			CargoMovement<StationCargoList, VehicleCargoList>(source, destination, max_move), load_place(load_place) {}
85 	bool operator()(CargoPacket *cp);
86 };
87 
88 /** Action of reserving cargo from a station to be loaded onto a vehicle. */
89 class CargoReservation : public CargoLoad {
90 public:
CargoReservation(StationCargoList * source,VehicleCargoList * destination,uint max_move,TileIndex load_place)91 	CargoReservation(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex load_place) :
92 			CargoLoad(source, destination, max_move, load_place) {}
93 	bool operator()(CargoPacket *cp);
94 };
95 
96 /** Action of returning previously reserved cargo from the vehicle to the station. */
97 class CargoReturn : public CargoMovement<VehicleCargoList, StationCargoList> {
98 	StationID next;
99 public:
CargoReturn(VehicleCargoList * source,StationCargoList * destination,uint max_move,StationID next)100 	CargoReturn(VehicleCargoList *source, StationCargoList *destination, uint max_move, StationID next) :
101 			CargoMovement<VehicleCargoList, StationCargoList>(source, destination, max_move), next(next) {}
102 	bool operator()(CargoPacket *cp);
103 };
104 
105 /** Action of shifting cargo from one vehicle to another. */
106 class CargoShift : public CargoMovement<VehicleCargoList, VehicleCargoList> {
107 public:
CargoShift(VehicleCargoList * source,VehicleCargoList * destination,uint max_move)108 	CargoShift(VehicleCargoList *source, VehicleCargoList *destination, uint max_move) :
109 			CargoMovement<VehicleCargoList, VehicleCargoList>(source, destination, max_move) {}
110 	bool operator()(CargoPacket *cp);
111 };
112 
113 /** Action of rerouting cargo between different cargo lists and/or next hops. */
114 template<class Tlist>
115 class CargoReroute : public CargoMovement<Tlist, Tlist> {
116 protected:
117 	StationID avoid;
118 	StationID avoid2;
119 	const GoodsEntry *ge;
120 public:
CargoReroute(Tlist * source,Tlist * dest,uint max_move,StationID avoid,StationID avoid2,const GoodsEntry * ge)121 	CargoReroute(Tlist *source, Tlist *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
122 			CargoMovement<Tlist, Tlist>(source, dest, max_move), avoid(avoid), avoid2(avoid2), ge(ge) {}
123 };
124 
125 /** Action of rerouting cargo in a station. */
126 class StationCargoReroute : public CargoReroute<StationCargoList> {
127 public:
StationCargoReroute(StationCargoList * source,StationCargoList * dest,uint max_move,StationID avoid,StationID avoid2,const GoodsEntry * ge)128 	StationCargoReroute(StationCargoList *source, StationCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
129 				CargoReroute<StationCargoList>(source, dest, max_move, avoid, avoid2, ge) {}
130 	bool operator()(CargoPacket *cp);
131 };
132 
133 /** Action of rerouting cargo staged for transfer in a vehicle. */
134 class VehicleCargoReroute : public CargoReroute<VehicleCargoList> {
135 public:
VehicleCargoReroute(VehicleCargoList * source,VehicleCargoList * dest,uint max_move,StationID avoid,StationID avoid2,const GoodsEntry * ge)136 	VehicleCargoReroute(VehicleCargoList *source, VehicleCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
137 			CargoReroute<VehicleCargoList>(source, dest, max_move, avoid, avoid2, ge)
138 	{
139 		assert(this->max_move <= source->ActionCount(VehicleCargoList::MTA_TRANSFER));
140 	}
141 	bool operator()(CargoPacket *cp);
142 };
143 
144 #endif /* CARGOACTION_H */
145