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 /** The pool of autoreplace "orders". */
19 EngineRenewPool
_enginerenew_pool("EngineRenew");
20 INSTANTIATE_POOL_METHODS(EngineRenew
)
23 * Retrieves the EngineRenew that specifies the replacement of the given
24 * engine type from the given renewlist
26 static EngineRenew
*GetEngineReplacement(EngineRenewList erl
, EngineID engine
, GroupID group
)
28 EngineRenew
*er
= (EngineRenew
*)erl
;
31 if (er
->from
== engine
&& er
->group_id
== group
) return er
;
38 * Remove all engine replacement settings for the company.
39 * @param erl The renewlist for a given company.
40 * @return The new renewlist for the company.
42 void RemoveAllEngineReplacement(EngineRenewList
*erl
)
44 EngineRenew
*er
= (EngineRenew
*)(*erl
);
52 *erl
= NULL
; // Empty list
56 * Retrieve the engine replacement in a given renewlist for an original engine type.
57 * @param erl The renewlist to search in.
58 * @param engine Engine type to be replaced.
59 * @param group The group related to this replacement.
60 * @param[out] replace_when_old Set to true if the replacement should be done when old.
61 * @return The engine type to replace with, or INVALID_ENGINE if no
62 * replacement is in the list.
64 EngineID
EngineReplacement(EngineRenewList erl
, EngineID engine
, GroupID group
, bool *replace_when_old
)
66 const EngineRenew
*er
= GetEngineReplacement(erl
, engine
, group
);
67 if (er
== NULL
&& (group
== DEFAULT_GROUP
|| (Group::IsValidID(group
) && !Group::Get(group
)->replace_protection
))) {
68 /* We didn't find anything useful in the vehicle's own group so we will try ALL_GROUP */
69 er
= GetEngineReplacement(erl
, engine
, ALL_GROUP
);
71 if (replace_when_old
!= NULL
) *replace_when_old
= er
== NULL
? false : er
->replace_when_old
;
72 return er
== NULL
? INVALID_ENGINE
: er
->to
;
76 * Add an engine replacement to the given renewlist.
77 * @param erl The renewlist to add to.
78 * @param old_engine The original engine type.
79 * @param new_engine The replacement engine type.
80 * @param group The group related to this replacement.
81 * @param replace_when_old Replace when old or always?
82 * @param flags The calling command flags.
83 * @return 0 on success, CMD_ERROR on failure.
85 CommandCost
AddEngineReplacement(EngineRenewList
*erl
, EngineID old_engine
, EngineID new_engine
, GroupID group
, bool replace_when_old
, DoCommandFlag flags
)
87 /* Check if the old vehicle is already in the list */
88 EngineRenew
*er
= GetEngineReplacement(*erl
, old_engine
, group
);
90 if (flags
& DC_EXEC
) {
92 er
->replace_when_old
= replace_when_old
;
97 if (!EngineRenew::CanAllocateItem()) return CMD_ERROR
;
99 if (flags
& DC_EXEC
) {
100 er
= new EngineRenew(old_engine
, new_engine
);
101 er
->group_id
= group
;
102 er
->replace_when_old
= replace_when_old
;
104 /* Insert before the first element */
105 er
->next
= (EngineRenew
*)(*erl
);
106 *erl
= (EngineRenewList
)er
;
109 return CommandCost();
113 * Remove an engine replacement from a given renewlist.
114 * @param erl The renewlist from which to remove the replacement
115 * @param engine The original engine type.
116 * @param group The group related to this replacement.
117 * @param flags The calling command flags.
118 * @return 0 on success, CMD_ERROR on failure.
120 CommandCost
RemoveEngineReplacement(EngineRenewList
*erl
, EngineID engine
, GroupID group
, DoCommandFlag flags
)
122 EngineRenew
*er
= (EngineRenew
*)(*erl
);
123 EngineRenew
*prev
= NULL
;
126 if (er
->from
== engine
&& er
->group_id
== group
) {
127 if (flags
& DC_EXEC
) {
128 if (prev
== NULL
) { // First element
129 /* The second becomes the new first element */
130 *erl
= (EngineRenewList
)er
->next
;
132 /* Cut this element out */
133 prev
->next
= er
->next
;
137 return CommandCost();