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/>.
8 /** @file logic_signals_cmd.cpp Commands for modifying logic signal programs. */
10 #include "logic_signals.h"
11 #include "core/bitmath_func.hpp"
12 #include "window_func.h"
13 #include "command_func.h"
15 #include "table/strings.h"
16 #include "company_func.h"
19 * The main command for editing a signal program.
20 * @param tile The tile which contains the edited signal.
21 * @param flags Internal command handler stuff.
22 * @param p1 Bitstuffed items
23 * - p1 = (bit 0-2) - The Track part of the signal program tile.
24 * - p1 = (bit 3-5) - Subcommand to execute.
25 * - p1 = (bit 6-7) - The value to set to the signal program.
26 * @param p2 Target SignalReference for linking of two signals
27 * @return the cost of this operation (which is free), or an error
29 CommandCost
CmdProgramLogicSignal(TileIndex tile
, DoCommandFlag flags
, uint32 p1
, uint32 p2
, const char *text
)
31 Track track
= (Track
) GB(p1
, 0, 3);
32 uint32 sub_cmd
= GB(p1
, 3, 3);
33 uint32 value
= GB(p1
, 6, 2);
35 /* Start by checking tile ownership */
36 CommandCost ret
= CheckTileOwnership(tile
);
37 if (ret
.Failed()) return ret
;
39 SignalProgram
*program
= FindSignalProgram(tile
, track
);
42 if (flags
& DC_EXEC
) {
43 program
->own_default_state
= (SignalState
) value
;
46 else if (sub_cmd
== 2) {
47 if (flags
& DC_EXEC
) {
48 program
->trigger_state
= (SignalState
) value
;
51 else if (sub_cmd
== 3) {
52 if (flags
& DC_EXEC
) {
53 program
->signal_op
= (SignalOperator
) value
;
56 else if (sub_cmd
== 4) {
57 TileIndex target_tile
= p2
;
58 Track target_track
= SignalTrackFromTile(target_tile
);
60 if (tile
== target_tile
&& track
== target_track
) {
61 return_cmd_error(STR_ERROR_LINK_SIGNAL_TO_ITSELF
);
62 } else if (!IsPlainRailTile(target_tile
) || !HasSignalOnTrack(target_tile
, target_track
)) {
63 return_cmd_error(STR_ERROR_LINK_SIGNAL_NO_SIGNAL
);
64 } else if (CheckTileOwnership(target_tile
).Failed()) {
65 return_cmd_error(STR_ERROR_OWNED_BY
);
68 if (flags
& DC_EXEC
) {
69 program
->AddLink(target_tile
, target_track
, true);
72 else if (sub_cmd
== 5) {
74 program
->ClearAllLinks();
77 if (flags
& DC_EXEC
) {
78 /* Invalidate any open windows if something was changed */
79 InvalidateWindowData(WC_SIGNAL_PROGRAM
, GetSignalReference(tile
, track
));
81 /* Re-evaluate the signal state too */
82 program
->InputChanged(1);
85 /* No cost, this fun is free :) */