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) { |