Files
@ r22926:82779a967ee2
Branch filter:
Location: cpp/openttd-patchpack/source/src/cargoaction.h
r22926:82779a967ee2
5.8 KiB
text/x-c
Change: Modernise music control logic implementation (#6839)
Rewrite of almost the entire music control logic to a more modern style, hopefully also easier to understand. The old playlist handling made it look like arcane magic, which it doesn't have to be.
- Playlists are now stored in std::vector of objects instead of arrays of bytes with magic sentinel values, that need to be rotated around all the time. Position in playlist is stored as a simple index.
- The theme song is now reserved for the title screen, it doesn't play on any of the standard playlists, but is still available for use on custom playlists.
- When the player enters/leaves the game from the main menu, the music always restarts.
- Playback state (playing or not) is kept even if music becomes unavailable due to an empty playlist (or an empty music set), so it can restart immediately if music becomes available again.
- The shuffle algorithm was changed to a standard Fisher-Yates.
- Possibly better behavior when editing a custom playlist while it's playing.
- Custom playlists should be compatible.
- Framework for supporting custom playlists with songs from multiple music sets.
Rewrite of almost the entire music control logic to a more modern style, hopefully also easier to understand. The old playlist handling made it look like arcane magic, which it doesn't have to be.
- Playlists are now stored in std::vector of objects instead of arrays of bytes with magic sentinel values, that need to be rotated around all the time. Position in playlist is stored as a simple index.
- The theme song is now reserved for the title screen, it doesn't play on any of the standard playlists, but is still available for use on custom playlists.
- When the player enters/leaves the game from the main menu, the music always restarts.
- Playback state (playing or not) is kept even if music becomes unavailable due to an empty playlist (or an empty music set), so it can restart immediately if music becomes available again.
- The shuffle algorithm was changed to a standard Fisher-Yates.
- Possibly better behavior when editing a custom playlist while it's playing.
- Custom playlists should be compatible.
- Framework for supporting custom playlists with songs from multiple music sets.
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 | /* $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 cargoaction.h Actions to be applied to cargo packets. */
#ifndef CARGOACTION_H
#define CARGOACTION_H
#include "cargopacket.h"
/**
* Abstract action of removing cargo from a vehicle or a station.
* @tparam Tsource CargoList subclass to remove cargo from.
*/
template<class Tsource>
class CargoRemoval {
protected:
Tsource *source; ///< Source of the cargo.
uint max_move; ///< Maximum amount of cargo to be removed with this action.
uint Preprocess(CargoPacket *cp);
bool Postprocess(CargoPacket *cp, uint remove);
public:
CargoRemoval(Tsource *source, uint max_move) : source(source), max_move(max_move) {}
/**
* Returns how much more cargo can be removed with this action.
* @return Amount of cargo this action can still remove.
*/
uint MaxMove() { return this->max_move; }
bool operator()(CargoPacket *cp);
};
/** Action of final delivery of cargo. */
class CargoDelivery : public CargoRemoval<VehicleCargoList> {
protected:
CargoPayment *payment; ///< Payment object where payments will be registered.
public:
CargoDelivery(VehicleCargoList *source, uint max_move, CargoPayment *payment) :
CargoRemoval<VehicleCargoList>(source, max_move), payment(payment) {}
bool operator()(CargoPacket *cp);
};
/**
* Abstract action for moving cargo from one list to another.
* @tparam Tsource CargoList subclass to remove cargo from.
* @tparam Tdest CargoList subclass to add cargo to.
*/
template<class Tsource, class Tdest>
class CargoMovement {
protected:
Tsource *source; ///< Source of the cargo.
Tdest *destination; ///< Destination for the cargo.
uint max_move; ///< Maximum amount of cargo to be moved with this action.
CargoPacket *Preprocess(CargoPacket *cp);
public:
CargoMovement(Tsource *source, Tdest *destination, uint max_move) : source(source), destination(destination), max_move(max_move) {}
/**
* Returns how much more cargo can be moved with this action.
* @return Amount of cargo this action can still move.
*/
uint MaxMove() { return this->max_move; }
};
/** Action of transferring cargo from a vehicle to a station. */
class CargoTransfer : public CargoMovement<VehicleCargoList, StationCargoList> {
public:
CargoTransfer(VehicleCargoList *source, StationCargoList *destination, uint max_move) :
CargoMovement<VehicleCargoList, StationCargoList>(source, destination, max_move) {}
bool operator()(CargoPacket *cp);
};
/** Action of loading cargo from a station onto a vehicle. */
class CargoLoad : public CargoMovement<StationCargoList, VehicleCargoList> {
protected:
TileIndex load_place; ///< TileIndex to be saved in the packets' loaded_at_xy.
public:
CargoLoad(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex load_place) :
CargoMovement<StationCargoList, VehicleCargoList>(source, destination, max_move), load_place(load_place) {}
bool operator()(CargoPacket *cp);
};
/** Action of reserving cargo from a station to be loaded onto a vehicle. */
class CargoReservation : public CargoLoad {
public:
CargoReservation(StationCargoList *source, VehicleCargoList *destination, uint max_move, TileIndex load_place) :
CargoLoad(source, destination, max_move, load_place) {}
bool operator()(CargoPacket *cp);
};
/** Action of returning previously reserved cargo from the vehicle to the station. */
class CargoReturn : public CargoMovement<VehicleCargoList, StationCargoList> {
StationID next;
public:
CargoReturn(VehicleCargoList *source, StationCargoList *destination, uint max_move, StationID next) :
CargoMovement<VehicleCargoList, StationCargoList>(source, destination, max_move), next(next) {}
bool operator()(CargoPacket *cp);
};
/** Action of shifting cargo from one vehicle to another. */
class CargoShift : public CargoMovement<VehicleCargoList, VehicleCargoList> {
public:
CargoShift(VehicleCargoList *source, VehicleCargoList *destination, uint max_move) :
CargoMovement<VehicleCargoList, VehicleCargoList>(source, destination, max_move) {}
bool operator()(CargoPacket *cp);
};
/** Action of rerouting cargo between different cargo lists and/or next hops. */
template<class Tlist>
class CargoReroute : public CargoMovement<Tlist, Tlist> {
protected:
StationID avoid;
StationID avoid2;
const GoodsEntry *ge;
public:
CargoReroute(Tlist *source, Tlist *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
CargoMovement<Tlist, Tlist>(source, dest, max_move), avoid(avoid), avoid2(avoid2), ge(ge) {}
};
/** Action of rerouting cargo in a station. */
class StationCargoReroute : public CargoReroute<StationCargoList> {
public:
StationCargoReroute(StationCargoList *source, StationCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
CargoReroute<StationCargoList>(source, dest, max_move, avoid, avoid2, ge) {}
bool operator()(CargoPacket *cp);
};
/** Action of rerouting cargo staged for transfer in a vehicle. */
class VehicleCargoReroute : public CargoReroute<VehicleCargoList> {
public:
VehicleCargoReroute(VehicleCargoList *source, VehicleCargoList *dest, uint max_move, StationID avoid, StationID avoid2, const GoodsEntry *ge) :
CargoReroute<VehicleCargoList>(source, dest, max_move, avoid, avoid2, ge)
{
assert(this->max_move <= source->ActionCount(VehicleCargoList::MTA_TRANSFER));
}
bool operator()(CargoPacket *cp);
};
#endif /* CARGOACTION_H */
|