1 /* $Id: autoreplace.cpp 24950 2013-01-31 10:21:04Z peter1138 $ */
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
10 /** @file autoreplace.cpp Management of replacement lists. */
13 #include "command_func.h"
15 #include "autoreplace_base.h"
16 #include "core/pool_func.hpp"
18 #include "safeguards.h"
20 /** The pool of autoreplace "orders". */
21 EngineRenewPool
_enginerenew_pool("EngineRenew");
22 INSTANTIATE_POOL_METHODS(EngineRenew
)
25 * Retrieves the EngineRenew that specifies the replacement of the given
26 * engine type from the given renewlist
28 static EngineRenew
*GetEngineReplacement(EngineRenewList erl
, EngineID engine
, GroupID group
)
30 EngineRenew
*er
= (EngineRenew
*)erl
;
32 while (er
!= nullptr) {
33 if (er
->from
== engine
&& GroupIsInGroup(group
, er
->group_id
)) return er
;
40 * Remove all engine replacement settings for the company.
41 * @param erl The renewlist for a given company.
42 * @return The new renewlist for the company.
44 void RemoveAllEngineReplacement(EngineRenewList
*erl
)
46 EngineRenew
*er
= (EngineRenew
*)(*erl
);
49 while (er
!= nullptr) {
54 *erl
= nullptr; // Empty list
58 * Retrieve the engine replacement in a given renewlist for an original engine type.
59 * @param erl The renewlist to search in.
60 * @param engine Engine type to be replaced.
61 * @param group The group related to this replacement.
62 * @param[out] replace_when_old Set to true if the replacement should be done when old.
63 * @return The engine type to replace with, or INVALID_ENGINE if no
64 * replacement is in the list.
66 EngineID
EngineReplacement(EngineRenewList erl
, EngineID engine
, GroupID group
, bool *replace_when_old
)
68 const EngineRenew
*er
= GetEngineReplacement(erl
, engine
, group
);
69 if (er
== nullptr && (group
== DEFAULT_GROUP
|| (Group::IsValidID(group
) && !Group::Get(group
)->replace_protection
))) {
70 /* We didn't find anything useful in the vehicle's own group so we will try ALL_GROUP */
71 er
= GetEngineReplacement(erl
, engine
, ALL_GROUP
);
73 if (replace_when_old
!= nullptr) *replace_when_old
= er
== nullptr ? false : er
->replace_when_old
;
74 return er
== nullptr ? INVALID_ENGINE
: er
->to
;
78 * Add an engine replacement to the given renewlist.
79 * @param erl The renewlist to add to.
80 * @param old_engine The original engine type.
81 * @param new_engine The replacement engine type.
82 * @param group The group related to this replacement.
83 * @param replace_when_old Replace when old or always?
84 * @param flags The calling command flags.
85 * @return 0 on success, CommandError() on failure.
87 CommandCost
AddEngineReplacement(EngineRenewList
*erl
, EngineID old_engine
, EngineID new_engine
, GroupID group
, bool replace_when_old
, DoCommandFlag flags
)
89 /* Check if the old vehicle is already in the list */
90 EngineRenew
*er
= GetEngineReplacement(*erl
, old_engine
, group
);
92 if (flags
& DC_EXEC
) {
94 er
->replace_when_old
= replace_when_old
;
99 if (!EngineRenew::CanAllocateItem()) return CommandError();
101 if (flags
& DC_EXEC
) {
102 er
= new EngineRenew(old_engine
, new_engine
);
103 er
->group_id
= group
;
104 er
->replace_when_old
= replace_when_old
;
106 /* Insert before the first element */
107 er
->next
= (EngineRenew
*)(*erl
);
108 *erl
= (EngineRenewList
)er
;
111 return CommandCost();
115 * Remove an engine replacement from a given renewlist.
116 * @param erl The renewlist from which to remove the replacement
117 * @param engine The original engine type.
118 * @param group The group related to this replacement.
119 * @param flags The calling command flags.
120 * @return 0 on success, CommandError() on failure.
122 CommandCost
RemoveEngineReplacement(EngineRenewList
*erl
, EngineID engine
, GroupID group
, DoCommandFlag flags
)
124 EngineRenew
*er
= (EngineRenew
*)(*erl
);
125 EngineRenew
*prev
= nullptr;
127 while (er
!= nullptr) {
128 if (er
->from
== engine
&& er
->group_id
== group
) {
129 if (flags
& DC_EXEC
) {
130 if (prev
== nullptr) { // First element
131 /* The second becomes the new first element */
132 *erl
= (EngineRenewList
)er
->next
;
134 /* Cut this element out */
135 prev
->next
= er
->next
;
139 return CommandCost();
145 return CommandError();