rail_cmd.c
changeset 1084 95b7385f8b7b
parent 1066 eaef1465d3ab
child 1093 4fdc46eaf423
equal deleted inserted replaced
1083:8e64dc3ed29f 1084:95b7385f8b7b
   860 	}
   860 	}
   861 	return 0;
   861 	return 0;
   862 }
   862 }
   863 
   863 
   864 
   864 
   865 /*	build signals, alternate between double/single, signal/semaphore, pre/exit/combo -signals
   865 /* build signals, alternate between double/single, signal/semaphore,
   866 		p1 = (lower 3 bytes)	- track-orientation
   866  * pre/exit/combo-signals
   867 		p1 = (byte 4)					- semaphores/signals
   867  * p1 bits 0-2 - track-orientation, valid values: 0-5
   868 		p2 = used for CmdBuildManySignals() to copy style first signal
   868  * p1 bit  3   - choose semaphores/signals or cycle normal/pre/exit/combo
       
   869  *               depending on context
       
   870  * p2 = used for CmdBuildManySignals() to copy style of first signal
   869  */
   871  */
   870 int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   872 int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   871 {
   873 {
   872 	uint tile;
   874 	TileIndex tile = TILE_FROM_XY(x, y);
       
   875 	bool semaphore;
       
   876 	bool pre_signal;
       
   877 	uint track = p1 & 0x7;
   873 	byte m5;
   878 	byte m5;
   874 	int32 cost;
   879 	int32 cost;
   875 	int track = p1 & 0x7;
   880 
   876 	byte a,b,c,d;
   881 	if (!(track < 6) || // only 6 possible track-combinations
   877 
   882 			!IsTileType(tile, MP_RAILWAY) ||
   878 	assert(track >= 0 && track < 6); // only 6 possible track-combinations
   883 			!EnsureNoVehicle(tile))
   879 
   884 		return CMD_ERROR;
   880 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   885 
   881 
   886 	// Protect against invalid signal copying
   882 	tile = TILE_FROM_XY(x,y);
   887 	if (p2 != 0 && (p2 & _signals_table_both[track]) == 0)
   883 
   888 		return CMD_ERROR;
   884 	if (!EnsureNoVehicle(tile))
   889 
   885 		return CMD_ERROR;
   890 	m5 = _map5[tile];
   886 
   891 
   887 	// must be railway, and not a depot, and it must have a track in the suggested position.
   892 	if (m5 & 0x80 || // mustn't be a depot
   888 	if (!IsTileType(tile, MP_RAILWAY) || (m5 = _map5[tile], m5 & 0x80) || !HASBIT(m5, track))
   893 			!HASBIT(m5, track)) // track must exist
   889 		return CMD_ERROR;
   894 		return CMD_ERROR;
       
   895 
       
   896 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
   890 
   897 
   891 	_error_message = STR_1005_NO_SUITABLE_RAILROAD_TRACK;
   898 	_error_message = STR_1005_NO_SUITABLE_RAILROAD_TRACK;
   892 
   899 
   893 	// check rail combination
       
   894 	{
   900 	{
   895 		byte m = m5 & RAIL_BIT_MASK;
   901 		byte m = m5 & RAIL_BIT_MASK;
   896 		if (m != RAIL_BIT_DIAG1 && m != RAIL_BIT_DIAG2 && m != RAIL_BIT_UPPER && m != RAIL_BIT_LOWER &&
   902 		if (m != RAIL_BIT_DIAG1 &&
   897 				m != RAIL_BIT_LEFT && m != RAIL_BIT_RIGHT && m != (RAIL_BIT_UPPER|RAIL_BIT_LOWER) && m != (RAIL_BIT_LEFT|RAIL_BIT_RIGHT))
   903 				m != RAIL_BIT_DIAG2 &&
       
   904 				m != RAIL_BIT_UPPER &&
       
   905 				m != RAIL_BIT_LOWER &&
       
   906 				m != RAIL_BIT_LEFT &&
       
   907 				m != RAIL_BIT_RIGHT &&
       
   908 				m != (RAIL_BIT_UPPER | RAIL_BIT_LOWER) &&
       
   909 				m != (RAIL_BIT_LEFT | RAIL_BIT_RIGHT))
   898 			return CMD_ERROR;
   910 			return CMD_ERROR;
   899 	}
   911 	}
   900 
   912 
   901 	// check ownership
   913 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   902 	if (!CheckTileOwnership(tile))
   914 
   903 		return CMD_ERROR;
   915 	// Same bit, used in different contexts
   904 
   916 	semaphore = pre_signal = HASBIT(p1, 3);
   905 	// calculate masks for..
   917 
   906 	a = _signals_table[track];      // .. signal for this track in one direction
   918 	if ((_map3_lo[tile] & _signals_table_both[track]) == 0) {
   907 	b = _signals_table[track + 8];  // .. signal for this track in the other direction
   919 		// build new signals
   908 	c = a | b;											// .. 2-way signal for this track
       
   909 
       
   910 	// If it had signals previously it is free to change orientation/pre-exit-combo signals
       
   911 	cost = 0;
       
   912 	if (!(m5 & RAIL_TYPE_SIGNALS)) {
       
   913 		cost = _price.build_signals;
   920 		cost = _price.build_signals;
   914 	} else {
   921 	} else {
   915 		d = _map3_lo[tile] & c;					// mask of built signals. it only affects &0xF0
   922 		if (p2 != 0 &&
   916 		if (d == 0) cost += _price.build_signals; // no signals built yet
   923 				((semaphore && !HASBIT(_map3_hi[tile], 2)) ||
   917 	// if converting signals<->semaphores, charge the player for it
   924 				(!semaphore && HASBIT(_map3_hi[tile], 2)))) {
   918 		if (p2 && ((HASBIT(p1, 3) && !HASBIT(_map3_hi[tile], 2)) || (!HASBIT(p1, 3) && HASBIT(_map3_hi[tile], 2)) ) )
   925 			// convert signals <-> semaphores
   919 			cost += _price.build_signals + _price.remove_signals;
   926 			cost = _price.build_signals + _price.remove_signals;
       
   927 		} else {
       
   928 			// it is free to change orientation/pre-exit-combo signals
       
   929 			cost = 0;
       
   930 		}
   920 	}
   931 	}
   921 
   932 
   922 	if (flags & DC_EXEC) {
   933 	if (flags & DC_EXEC) {
   923 
   934 		if (!(m5 & RAIL_TYPE_SIGNALS)) {
   924 
   935 			// there are no signals at all on this tile yet
   925 		if (!(m5 & RAIL_TYPE_SIGNALS)) {		// if there are no signals yet present on the track
       
   926 			_map5[tile] |= RAIL_TYPE_SIGNALS; // change into signals
   936 			_map5[tile] |= RAIL_TYPE_SIGNALS; // change into signals
   927 			_map2[tile] |= 0xF0;              // all signals are on
   937 			_map2[tile] |= 0xF0;              // all signals are on
   928 			_map3_lo[tile] &= ~0xF0;          // no signals built by default
   938 			_map3_lo[tile] &= ~0xF0;          // no signals built by default
   929 			_map3_hi[tile] = (p1 & 8) ? 4 : 0;// initial presignal state, semaphores depend on ctrl key
   939 			_map3_hi[tile] = semaphore ? 4 : 0;
   930 			d = 0;														// no existing signals
   940 		}
   931 			if (!p2)
   941 
   932 				goto ignore_presig;
   942 		if (p2 == 0) {
   933 		}
   943 			if ((_map3_lo[tile] & _signals_table_both[track]) == 0) {
   934 
   944 				// build new signals
   935 		if (!p2) { // not called from CmdBuildManySignals
   945 				_map3_lo[tile] |= _signals_table_both[track];
   936 			if (!HASBIT(p1, 3)) { // not CTRL pressed
   946 			} else {
   937 	ignore_presig:
   947 				if (pre_signal) {
   938 				// Alternate between a|b, b, a
   948 					// cycle between normal -> pre -> exit -> combo -> ...
   939 				if ( d != 0 && d != a)
   949 					byte type = (_map3_hi[tile] + 1) & 0x03;
   940 					c = (d == c)?b:a;
   950 					_map3_hi[tile] &= ~0x03;
   941 
   951 					_map3_hi[tile] |= type;
   942 				_map3_lo[tile] = (_map3_lo[tile]&~(a|b)) | c;
   952 				} else {
   943 			} else // CTRL pressed
   953 					// cycle between two-way -> one-way -> one-way -> ...
   944 				_map3_hi[tile] = (_map3_hi[tile] & ~3) | ((_map3_hi[tile] + 1) & 3);
   954 					switch (track) {
       
   955 						case 3:
       
   956 						case 5: {
       
   957 							byte signal = (_map3_lo[tile] - 0x10) & 0x30;
       
   958 							if (signal == 0) signal = 0x30;
       
   959 							_map3_lo[tile] &= ~0x30;
       
   960 							_map3_lo[tile] |= signal;
       
   961 							break;
       
   962 						}
       
   963 
       
   964 						default: {
       
   965 							byte signal = (_map3_lo[tile] - 0x40) & 0xC0;
       
   966 							if (signal == 0) signal = 0xC0;
       
   967 							_map3_lo[tile] &= ~0xC0;
       
   968 							_map3_lo[tile] |= signal;
       
   969 							break;
       
   970 						}
       
   971 					}
       
   972 				}
       
   973 			}
   945 		} else {
   974 		} else {
   946 			/* If CmdBuildManySignals is called with copying signals, just copy the style of the first signal
   975 			/* If CmdBuildManySignals is called with copying signals, just copy the
   947 			* given as parameter by CmdBuildManySignals */
   976 			 * style of the first signal given as parameter by CmdBuildManySignals */
   948 			switch (track) {
   977 			_map3_lo[tile] &= ~_signals_table_both[track];
   949 			case 2: case 4: _map3_lo[tile] = (p2&0xC0) | (_map3_lo[tile]&~0xC0); break;
   978 			_map3_lo[tile] |= p2 & _signals_table_both[track];
   950 			case 3: case 5: _map3_lo[tile] = (p2&0x30) | (_map3_lo[tile]&~0x30); break;
       
   951 			default : _map3_lo[tile] = (p2&0xF0) | (_map3_lo[tile]&0xF);
       
   952 			}
       
   953 			// convert between signal<->semaphores when dragging
   979 			// convert between signal<->semaphores when dragging
   954 			HASBIT(p1, 3) ? SETBIT(_map3_hi[tile], 2) : CLRBIT(_map3_hi[tile], 2);
   980 			if (semaphore)
       
   981 				SETBIT(_map3_hi[tile], 2);
       
   982 			else
       
   983 				CLRBIT(_map3_hi[tile], 2);
   955 		}
   984 		}
   956 
   985 
   957 		MarkTileDirtyByTile(tile);
   986 		MarkTileDirtyByTile(tile);
   958 		SetSignalsOnBothDir(tile, track);
   987 		SetSignalsOnBothDir(tile, track);
   959 	}
   988 	}