774 * have any signals, bit 4 (cycle signal-type) is ignored |
774 * have any signals, bit 4 (cycle signal-type) is ignored |
775 * @param tile tile where to build the signals |
775 * @param tile tile where to build the signals |
776 * @param flags operation to perform |
776 * @param flags operation to perform |
777 * @param p1 various bitstuffed elements |
777 * @param p1 various bitstuffed elements |
778 * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum) |
778 * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum) |
779 * - p1 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) |
779 * - p1 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal or (for bit 7) toggle variant (CTRL-toggle) |
780 * - p1 = (bit 4) - 0 = signals, 1 = semaphores |
780 * - p1 = (bit 4) - 0 = signals, 1 = semaphores |
|
781 * - p1 = (bit 5-6) - type of the signal, for valid values see enum SignalType in rail_map.h |
|
782 * - p1 = (bit 7) - convert the present signal type and variant |
781 * @param p2 used for CmdBuildManySignals() to copy direction of first signal |
783 * @param p2 used for CmdBuildManySignals() to copy direction of first signal |
782 * TODO: p2 should be replaced by two bits for "along" and "against" the track. |
784 * TODO: p2 should be replaced by two bits for "along" and "against" the track. |
783 */ |
785 */ |
784 CommandCost CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
786 CommandCost CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
785 { |
787 { |
786 Track track = (Track)GB(p1, 0, 3); |
788 Track track = (Track)GB(p1, 0, 3); |
787 bool pre_signal = HasBit(p1, 3); |
789 bool ctrl_pressed = HasBit(p1, 3); // was the CTRL button pressed |
788 SignalVariant sigvar = (pre_signal ^ HasBit(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC; |
790 SignalVariant sigvar = (ctrl_pressed ^ HasBit(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC; // the signal variant of the new signal |
|
791 SignalType sigtype = (SignalType)GB(p1, 5, 2); // the signal type of the new signal |
|
792 bool convert_signal = HasBit(p1, 7); // convert button pressed |
789 CommandCost cost; |
793 CommandCost cost; |
790 |
794 |
791 if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoTrainOnTrack(tile, track)) |
795 if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoTrainOnTrack(tile, track)) |
792 return CMD_ERROR; |
796 return CMD_ERROR; |
793 |
797 |
796 |
800 |
797 /* You can only build signals on plain rail tiles, and the selected track must exist */ |
801 /* You can only build signals on plain rail tiles, and the selected track must exist */ |
798 if (!IsPlainRailTile(tile) || !HasTrack(tile, track)) return CMD_ERROR; |
802 if (!IsPlainRailTile(tile) || !HasTrack(tile, track)) return CMD_ERROR; |
799 |
803 |
800 if (!CheckTileOwnership(tile)) return CMD_ERROR; |
804 if (!CheckTileOwnership(tile)) return CMD_ERROR; |
801 |
|
802 _error_message = STR_1005_NO_SUITABLE_RAILROAD_TRACK; |
|
803 |
805 |
804 { |
806 { |
805 /* See if this is a valid track combination for signals, (ie, no overlap) */ |
807 /* See if this is a valid track combination for signals, (ie, no overlap) */ |
806 TrackBits trackbits = GetTrackBits(tile); |
808 TrackBits trackbits = GetTrackBits(tile); |
807 if (KillFirstBit(trackbits) != TRACK_BIT_NONE && /* More than one track present */ |
809 if (KillFirstBit(trackbits) != TRACK_BIT_NONE && /* More than one track present */ |
808 trackbits != TRACK_BIT_HORZ && |
810 trackbits != TRACK_BIT_HORZ && |
809 trackbits != TRACK_BIT_VERT) { |
811 trackbits != TRACK_BIT_VERT) { |
810 return CMD_ERROR; |
812 return_cmd_error(STR_1005_NO_SUITABLE_RAILROAD_TRACK); |
811 } |
813 } |
812 } |
814 } |
|
815 |
|
816 /* you can not convert a signal if no signal is on track */ |
|
817 if (convert_signal && !HasSignalOnTrack(tile, track)) return CMD_ERROR; |
813 |
818 |
814 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
819 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
815 |
820 |
816 if (!HasSignalOnTrack(tile, track)) { |
821 if (!HasSignalOnTrack(tile, track)) { |
817 /* build new signals */ |
822 /* build new signals */ |
818 cost = CommandCost(_price.build_signals); |
823 cost = CommandCost(_price.build_signals); |
819 } else { |
824 } else { |
820 if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) { |
825 if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) { |
821 /* convert signals <-> semaphores */ |
826 /* convert signals <-> semaphores */ |
822 cost = CommandCost(_price.build_signals + _price.remove_signals); |
827 cost = CommandCost(_price.build_signals + _price.remove_signals); |
|
828 |
|
829 } else if (convert_signal) { |
|
830 /* convert button pressed */ |
|
831 if (ctrl_pressed || GetSignalVariant(tile, track) != sigvar) { |
|
832 /* convert electric <-> semaphore */ |
|
833 cost = CommandCost(_price.build_signals + _price.remove_signals); |
|
834 } else { |
|
835 /* it is free to change signal type: normal-pre-exit-combo */ |
|
836 cost = CommandCost(); |
|
837 } |
|
838 |
823 } else { |
839 } else { |
824 /* it is free to change orientation/pre-exit-combo signals */ |
840 /* it is free to change orientation/pre-exit-combo signals */ |
825 cost = CommandCost(); |
841 cost = CommandCost(); |
826 } |
842 } |
827 } |
843 } |
830 if (!HasSignals(tile)) { |
846 if (!HasSignals(tile)) { |
831 /* there are no signals at all on this tile yet */ |
847 /* there are no signals at all on this tile yet */ |
832 SetHasSignals(tile, true); |
848 SetHasSignals(tile, true); |
833 SetSignalStates(tile, 0xF); // all signals are on |
849 SetSignalStates(tile, 0xF); // all signals are on |
834 SetPresentSignals(tile, 0); // no signals built by default |
850 SetPresentSignals(tile, 0); // no signals built by default |
835 SetSignalType(tile, track, SIGTYPE_NORMAL); |
851 SetSignalType(tile, track, sigtype); |
836 SetSignalVariant(tile, track, sigvar); |
852 SetSignalVariant(tile, track, sigvar); |
837 } |
853 } |
838 |
854 |
839 if (p2 == 0) { |
855 if (p2 == 0) { |
840 if (!HasSignalOnTrack(tile, track)) { |
856 if (!HasSignalOnTrack(tile, track)) { |
841 /* build new signals */ |
857 /* build new signals */ |
842 SetPresentSignals(tile, GetPresentSignals(tile) | SignalOnTrack(track)); |
858 SetPresentSignals(tile, GetPresentSignals(tile) | SignalOnTrack(track)); |
843 SetSignalType(tile, track, SIGTYPE_NORMAL); |
859 SetSignalType(tile, track, sigtype); |
844 SetSignalVariant(tile, track, sigvar); |
860 SetSignalVariant(tile, track, sigvar); |
845 } else { |
861 } else { |
846 if (pre_signal) { |
862 if (convert_signal) { |
|
863 /* convert signal button pressed */ |
|
864 if (ctrl_pressed) { |
|
865 /* toggle the pressent signal variant: SIG_ELECTRIC <-> SIG_SEMAPHORE */ |
|
866 SetSignalVariant(tile, track, (GetSignalVariant(tile, track) == SIG_ELECTRIC) ? SIG_SEMAPHORE : SIG_ELECTRIC); |
|
867 |
|
868 } else { |
|
869 /* convert the present signal to the chosen type and variant */ |
|
870 SetSignalType(tile, track, sigtype); |
|
871 SetSignalVariant(tile, track, sigvar); |
|
872 } |
|
873 |
|
874 } else if (ctrl_pressed) { |
847 /* cycle between normal -> pre -> exit -> combo -> ... */ |
875 /* cycle between normal -> pre -> exit -> combo -> ... */ |
848 SignalType type = GetSignalType(tile, track); |
876 sigtype = GetSignalType(tile, track); |
849 |
877 |
850 SetSignalType(tile, track, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1)); |
878 SetSignalType(tile, track, sigtype == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(sigtype + 1)); |
851 } else { |
879 } else { |
|
880 /* cycle the signal side: both -> left -> right -> both -> ... */ |
852 CycleSignalSide(tile, track); |
881 CycleSignalSide(tile, track); |
853 } |
882 } |
854 } |
883 } |
855 } else { |
884 } else { |
856 /* If CmdBuildManySignals is called with copying signals, just copy the |
885 /* If CmdBuildManySignals is called with copying signals, just copy the |