rail_cmd.c
changeset 1066 eaef1465d3ab
parent 1059 fe97d81a1b4f
child 1084 95b7385f8b7b
equal deleted inserted replaced
1065:9a1065aa729e 1066:eaef1465d3ab
   871 {
   871 {
   872 	uint tile;
   872 	uint tile;
   873 	byte m5;
   873 	byte m5;
   874 	int32 cost;
   874 	int32 cost;
   875 	int track = p1 & 0x7;
   875 	int track = p1 & 0x7;
       
   876 	byte a,b,c,d;
   876 
   877 
   877 	assert(track >= 0 && track < 6); // only 6 possible track-combinations
   878 	assert(track >= 0 && track < 6); // only 6 possible track-combinations
   878 
   879 
   879 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   880 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   880 
   881 
   899 
   900 
   900 	// check ownership
   901 	// check ownership
   901 	if (!CheckTileOwnership(tile))
   902 	if (!CheckTileOwnership(tile))
   902 		return CMD_ERROR;
   903 		return CMD_ERROR;
   903 
   904 
       
   905 	// calculate masks for..
       
   906 	a = _signals_table[track];      // .. signal for this track in one direction
       
   907 	b = _signals_table[track + 8];  // .. signal for this track in the other direction
       
   908 	c = a | b;											// .. 2-way signal for this track
       
   909 
   904 	// If it had signals previously it is free to change orientation/pre-exit-combo signals
   910 	// If it had signals previously it is free to change orientation/pre-exit-combo signals
   905 	cost = 0;
   911 	cost = 0;
   906 	if (!(m5 & RAIL_TYPE_SIGNALS)) {
   912 	if (!(m5 & RAIL_TYPE_SIGNALS)) {
   907 		cost = _price.build_signals;
   913 		cost = _price.build_signals;
       
   914 	} else {
       
   915 		d = _map3_lo[tile] & c;					// mask of built signals. it only affects &0xF0
       
   916 		if (d == 0) cost += _price.build_signals; // no signals built yet
   908 	// if converting signals<->semaphores, charge the player for it
   917 	// if converting signals<->semaphores, charge the player for it
   909 	} else if (p2 && ((HASBIT(p1, 3) && !HASBIT(_map3_hi[tile], 2)) || (!HASBIT(p1, 3) && HASBIT(_map3_hi[tile], 2)) ) ) {
   918 		if (p2 && ((HASBIT(p1, 3) && !HASBIT(_map3_hi[tile], 2)) || (!HASBIT(p1, 3) && HASBIT(_map3_hi[tile], 2)) ) )
   910 		cost += _price.build_signals + _price.remove_signals;
   919 			cost += _price.build_signals + _price.remove_signals;
   911 	}
   920 	}
   912 
   921 
   913 	if (flags & DC_EXEC) {
   922 	if (flags & DC_EXEC) {
   914 
   923 
   915 
   924 
   916 		if (!(m5 & RAIL_TYPE_SIGNALS)) {		// if there are no signals yet present on the track
   925 		if (!(m5 & RAIL_TYPE_SIGNALS)) {		// if there are no signals yet present on the track
   917 			_map5[tile] |= RAIL_TYPE_SIGNALS; // change into signals
   926 			_map5[tile] |= RAIL_TYPE_SIGNALS; // change into signals
   918 			_map2[tile] |= 0xF0;              // all signals are on
   927 			_map2[tile] |= 0xF0;              // all signals are on
   919 			_map3_lo[tile] &= ~0xF0;          // no signals built by default
   928 			_map3_lo[tile] &= ~0xF0;          // no signals built by default
   920 			_map3_hi[tile] = (p1 & 8) ? 4 : 0;// initial presignal state, semaphores depend on ctrl key
   929 			_map3_hi[tile] = (p1 & 8) ? 4 : 0;// initial presignal state, semaphores depend on ctrl key
       
   930 			d = 0;														// no existing signals
   921 			if (!p2)
   931 			if (!p2)
   922 				goto ignore_presig;
   932 				goto ignore_presig;
   923 		}
   933 		}
   924 
   934 
   925 		if (!p2) { // not called from CmdBuildManySignals
   935 		if (!p2) { // not called from CmdBuildManySignals
   926 			if (!HASBIT(p1, 3)) { // not CTRL pressed
   936 			if (!HASBIT(p1, 3)) { // not CTRL pressed
   927 				byte a,b,c,d;
       
   928 	ignore_presig:
   937 	ignore_presig:
   929 				a = _signals_table[track];      // signal for this track in one direction
       
   930 				b = _signals_table[track + 8];  // signal for this track in the other direction
       
   931 				c = a | b;
       
   932 				d = _map3_lo[tile] & c;					// mask of built signals. it only affects &0xF0
       
   933 
       
   934 				// Alternate between a|b, b, a
   938 				// Alternate between a|b, b, a
   935 				if ( d != 0 && d != a) {
   939 				if ( d != 0 && d != a)
   936 					c = (d==c)?b:a;
   940 					c = (d == c)?b:a;
   937 				}
       
   938 
   941 
   939 				_map3_lo[tile] = (_map3_lo[tile]&~(a|b)) | c;
   942 				_map3_lo[tile] = (_map3_lo[tile]&~(a|b)) | c;
   940 			} else // CTRL pressed
   943 			} else // CTRL pressed
   941 				_map3_hi[tile] = (_map3_hi[tile] & ~3) | ((_map3_hi[tile] + 1) & 3);
   944 				_map3_hi[tile] = (_map3_hi[tile] & ~3) | ((_map3_hi[tile] + 1) & 3);
   942 		} else {
   945 		} else {
  1062 
  1065 
  1063 	return (error) ? CMD_ERROR : total_cost;
  1066 	return (error) ? CMD_ERROR : total_cost;
  1064 }
  1067 }
  1065 
  1068 
  1066 /* Remove signals
  1069 /* Remove signals
  1067  * p1 = unused
  1070  * p1 bits 0..2 = track
  1068  * p2 = unused
  1071  * p2 = unused
  1069  */
  1072  */
  1070 
  1073 
  1071 int32 CmdRemoveSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
  1074 int32 CmdRemoveSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
  1072 {
  1075 {
  1073 	TileInfo ti;
  1076 	TileInfo ti;
  1074 	uint tile;
  1077 	uint tile;
       
  1078 	int track = p1 & 0x7;
       
  1079 	byte a,b,c,d;
  1075 
  1080 
  1076 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
  1081 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
  1077 
  1082 
  1078 	FindLandscapeHeight(&ti, x, y);
  1083 	FindLandscapeHeight(&ti, x, y);
  1079 	tile = ti.tile;
  1084 	tile = ti.tile;
  1092 
  1097 
  1093 	/* Who owns the tile? */
  1098 	/* Who owns the tile? */
  1094 	if (_current_player != OWNER_WATER && !CheckTileOwnership(tile))
  1099 	if (_current_player != OWNER_WATER && !CheckTileOwnership(tile))
  1095 		return CMD_ERROR;
  1100 		return CMD_ERROR;
  1096 
  1101 
       
  1102 	// calculate already built signals
       
  1103 	a = _signals_table[track];      // signal for this track in one direction
       
  1104 	b = _signals_table[track + 8];  // signal for this track in the other direction
       
  1105 	c = a | b;
       
  1106 	d = _map3_lo[tile] & c;
       
  1107 
       
  1108 	/* no signals on selected track? */
       
  1109 	if (d == 0)
       
  1110 		return CMD_ERROR;
       
  1111 
  1097 	/* Do it? */
  1112 	/* Do it? */
  1098 	if (flags & DC_EXEC) {
  1113 	if (flags & DC_EXEC) {
  1099 		byte bits = _map5[tile];
  1114 		
  1100 		_map5[tile] &= ~RAIL_TYPE_SIGNALS;
  1115 		_map3_lo[tile] &= ~c;
  1101 		_map2[tile] &= ~0xF0;
  1116 
  1102 		CLRBIT(_map3_hi[tile], 2); // remove any possible semaphores
  1117 		/* removed last signal from tile? */
  1103 
  1118 		if ((_map3_lo[tile] & 0xF0) == 0) {
  1104 		/* TTDBUG: this code contains a bug, if a tile contains 2 signals
  1119 			_map5[tile] &= ~RAIL_TYPE_SIGNALS;
  1105 		 * on separate tracks, it won't work properly for the 2nd track */
  1120 			_map2[tile] &= ~0xF0;
  1106 		SetSignalsOnBothDir(tile, FIND_FIRST_BIT(bits & RAIL_BIT_MASK));
  1121 			CLRBIT(_map3_hi[tile], 2); // remove any possible semaphores
       
  1122 		}
       
  1123 		
       
  1124 		SetSignalsOnBothDir(tile, track);
  1107 
  1125 
  1108 		MarkTileDirtyByTile(tile);
  1126 		MarkTileDirtyByTile(tile);
  1109 	}
  1127 	}
  1110 
  1128 
  1111 	return _price.remove_signals;
  1129 	return _price.remove_signals;
  1227 			}
  1245 			}
  1228 		}
  1246 		}
  1229 		return cost;
  1247 		return cost;
  1230 
  1248 
  1231 	} else if ((m5 & RAIL_TYPE_MASK)==RAIL_TYPE_SIGNALS) {
  1249 	} else if ((m5 & RAIL_TYPE_MASK)==RAIL_TYPE_SIGNALS) {
  1232 		cost = DoCommandByTile(tile, 0, 0, flags, CMD_REMOVE_SIGNALS);
  1250 		cost = 0;
  1233 		if (cost == CMD_ERROR)
  1251 		if (_map3_lo[tile] & (_signals_table[0] | _signals_table[0 + 8])) { // check for signals in the first track
  1234 			return CMD_ERROR;
  1252 			ret = DoCommandByTile(tile, 0, 0, flags, CMD_REMOVE_SIGNALS);
       
  1253 			if (ret == CMD_ERROR)
       
  1254 				return CMD_ERROR;
       
  1255 			cost += ret;
       
  1256 		};
       
  1257 		if (_map3_lo[tile] & (_signals_table[3] | _signals_table[3 + 8])) { // check for signals in the other track
       
  1258 			ret = DoCommandByTile(tile, 3, 0, flags, CMD_REMOVE_SIGNALS);
       
  1259 			if (ret == CMD_ERROR)
       
  1260 				return CMD_ERROR;
       
  1261 			cost += ret;
       
  1262 		};
       
  1263 		
  1235 		m5 &= RAIL_BIT_MASK;
  1264 		m5 &= RAIL_BIT_MASK;
  1236 		if (flags & DC_EXEC)
  1265 		if (flags & DC_EXEC)
  1237 			goto regular_track;
  1266 			goto regular_track;
  1238 		return cost + _price.remove_rail;
  1267 		return cost + _price.remove_rail;
  1239 	} else if ( (m5 & (RAIL_TYPE_MASK|RAIL_DEPOT_UNUSED_BITS)) == RAIL_TYPE_DEPOT) {
  1268 	} else if ( (m5 & (RAIL_TYPE_MASK|RAIL_DEPOT_UNUSED_BITS)) == RAIL_TYPE_DEPOT) {