src/rail_cmd.cpp
changeset 7991 d6a95a5593ba
parent 7977 4a4e11757be5
child 8043 08dcb2d81d9d
equal deleted inserted replaced
7990:63211992f5c1 7991:d6a95a5593ba
   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