Fix some daylength issues, possible division by zero in main menu.
[openttd-joker.git] / src / logic_signals_cmd.cpp
blob60daae1921d6d39468907e28f54eac7cf9b3f57e
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 */
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"
14 #include "rail_map.h"
15 #include "table/strings.h"
16 #include "company_func.h"
18 /**
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);
41 if (sub_cmd == 1) {
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) {
73 if (flags & DC_EXEC)
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 :) */
86 return CommandCost();