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 } |