src/rail_cmd.cpp
branchgamebalance
changeset 9913 e79cd19772dd
parent 9912 1ac8aac92385
equal deleted inserted replaced
9912:1ac8aac92385 9913:e79cd19772dd
   187 	}
   187 	}
   188 	return i + 15;
   188 	return i + 15;
   189 }
   189 }
   190 
   190 
   191 
   191 
   192 static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
   192 static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
   193 {
   193 {
   194 	if (IsSteepSlope(tileh)) {
   194 	if (IsSteepSlope(tileh)) {
   195 		if (_patches.build_on_slopes && existing == 0) {
   195 		if (_patches.build_on_slopes && existing == 0) {
   196 			TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ);
   196 			TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ);
   197 			if (valid & rail_bits) return _eco->GetPrice(CEconomy::TERRAFORM);
   197 			if (valid & rail_bits) return _eco->GetPrice(CEconomy::TERRAFORM);
   229  * @param tile tile  to build on
   229  * @param tile tile  to build on
   230  * @param flags operation to perform
   230  * @param flags operation to perform
   231  * @param p1 railtype of being built piece (normal, mono, maglev)
   231  * @param p1 railtype of being built piece (normal, mono, maglev)
   232  * @param p2 rail track to build
   232  * @param p2 rail track to build
   233  */
   233  */
   234 int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   234 CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   235 {
   235 {
   236 	Slope tileh;
   236 	Slope tileh;
   237 	RailType railtype;
   237 	RailType railtype;
   238 	Track track;
   238 	Track track;
   239 	TrackBits trackbit;
   239 	TrackBits trackbit;
   240 	int32 cost = 0;
   240 	CommandCost cost = 0;
   241 	int32 ret;
   241 	CommandCost ret;
   242 
   242 
   243 	if (!ValParamRailtype(p1) || !ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
   243 	if (!ValParamRailtype(p1) || !ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
   244 	railtype = (RailType)p1;
   244 	railtype = (RailType)p1;
   245 	track = (Track)p2;
   245 	track = (Track)p2;
   246 
   246 
   355  * @param tile tile to remove track from
   355  * @param tile tile to remove track from
   356  * @param flags operation to perform
   356  * @param flags operation to perform
   357  * @param p1 unused
   357  * @param p1 unused
   358  * @param p2 rail orientation
   358  * @param p2 rail orientation
   359  */
   359  */
   360 int32 CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   360 CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   361 {
   361 {
   362 	Track track = (Track)p2;
   362 	Track track = (Track)p2;
   363 	TrackBits trackbit;
   363 	TrackBits trackbit;
   364 	int32 cost = 0;
   364 	CommandCost cost = 0;
   365 	bool crossing = false;
   365 	bool crossing = false;
   366 
   366 
   367 	if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
   367 	if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
   368 	trackbit = TrackToTrackBits(track);
   368 	trackbit = TrackToTrackBits(track);
   369 
   369 
   446 	{  0,  0 },
   446 	{  0,  0 },
   447 	{  0,  0 }
   447 	{  0,  0 }
   448 };
   448 };
   449 
   449 
   450 
   450 
   451 static int32 ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileIndex end)
   451 static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileIndex end)
   452 {
   452 {
   453 	int x = TileX(start);
   453 	int x = TileX(start);
   454 	int y = TileY(start);
   454 	int y = TileY(start);
   455 	int ex = TileX(end);
   455 	int ex = TileX(end);
   456 	int ey = TileY(end);
   456 	int ey = TileY(end);
   506  * @param p2 various bitstuffed elements
   506  * @param p2 various bitstuffed elements
   507  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
   507  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
   508  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   508  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   509  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   509  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   510  */
   510  */
   511 static int32 CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   511 static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   512 {
   512 {
   513 	int32 ret, total_cost = 0;
   513 	CommandCost ret, total_cost = 0;
   514 	Track track = (Track)GB(p2, 4, 3);
   514 	Track track = (Track)GB(p2, 4, 3);
   515 	Trackdir trackdir;
   515 	Trackdir trackdir;
   516 	byte mode = HASBIT(p2, 7);
   516 	byte mode = HASBIT(p2, 7);
   517 	RailType railtype = (RailType)GB(p2, 0, 4);
   517 	RailType railtype = (RailType)GB(p2, 0, 4);
   518 	TileIndex end_tile;
   518 	TileIndex end_tile;
   558  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
   558  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
   559  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   559  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   560  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   560  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   561  * @see CmdRailTrackHelper
   561  * @see CmdRailTrackHelper
   562  */
   562  */
   563 int32 CmdBuildRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   563 CommandCost CmdBuildRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   564 {
   564 {
   565 	return CmdRailTrackHelper(tile, flags, p1, CLRBIT(p2, 7));
   565 	return CmdRailTrackHelper(tile, flags, p1, CLRBIT(p2, 7));
   566 }
   566 }
   567 
   567 
   568 /** Build rail on a stretch of track.
   568 /** Build rail on a stretch of track.
   574  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
   574  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
   575  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   575  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   576  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   576  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   577  * @see CmdRailTrackHelper
   577  * @see CmdRailTrackHelper
   578  */
   578  */
   579 int32 CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   579 CommandCost CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   580 {
   580 {
   581 	return CmdRailTrackHelper(tile, flags, p1, SETBIT(p2, 7));
   581 	return CmdRailTrackHelper(tile, flags, p1, SETBIT(p2, 7));
   582 }
   582 }
   583 
   583 
   584 /** Build a train depot
   584 /** Build a train depot
   588  * @param p2 bit 0..1 entrance direction (DiagDirection)
   588  * @param p2 bit 0..1 entrance direction (DiagDirection)
   589  *
   589  *
   590  * @todo When checking for the tile slope,
   590  * @todo When checking for the tile slope,
   591  * distingush between "Flat land required" and "land sloped in wrong direction"
   591  * distingush between "Flat land required" and "land sloped in wrong direction"
   592  */
   592  */
   593 int32 CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   593 CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   594 {
   594 {
   595 	Depot *d;
   595 	Depot *d;
   596 	int32 cost, ret;
   596 	CommandCost cost, ret;
   597 	Slope tileh;
   597 	Slope tileh;
   598 
   598 
   599 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   599 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   600 
   600 
   601 	/* check railtype and valid direction for depot (0 through 3), 4 in total */
   601 	/* check railtype and valid direction for depot (0 through 3), 4 in total */
   657  * - p1 = (bit 3)   - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   657  * - p1 = (bit 3)   - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   658  * - p1 = (bit 4)   - 0 = signals, 1 = semaphores
   658  * - p1 = (bit 4)   - 0 = signals, 1 = semaphores
   659  * @param p2 used for CmdBuildManySignals() to copy direction of first signal
   659  * @param p2 used for CmdBuildManySignals() to copy direction of first signal
   660  * TODO: p2 should be replaced by two bits for "along" and "against" the track.
   660  * TODO: p2 should be replaced by two bits for "along" and "against" the track.
   661  */
   661  */
   662 int32 CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   662 CommandCost CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   663 {
   663 {
   664 	Track track = (Track)GB(p1, 0, 3);
   664 	Track track = (Track)GB(p1, 0, 3);
   665 	bool pre_signal = HASBIT(p1, 3);
   665 	bool pre_signal = HASBIT(p1, 3);
   666 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
   666 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
   667 	int32 cost;
   667 	CommandCost cost;
   668 
   668 
   669 	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicleOnGround(tile))
   669 	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicleOnGround(tile))
   670 		return CMD_ERROR;
   670 		return CMD_ERROR;
   671 
   671 
   672 	/* Protect against invalid signal copying */
   672 	/* Protect against invalid signal copying */
   754  * - p2 = (bit  3)    - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   754  * - p2 = (bit  3)    - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   755  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
   755  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
   756  * - p2 = (bit  5)    - 0 = build, 1 = remove signals
   756  * - p2 = (bit  5)    - 0 = build, 1 = remove signals
   757  * - p2 = (bit 24-31) - user defined signals_density
   757  * - p2 = (bit 24-31) - user defined signals_density
   758  */
   758  */
   759 static int32 CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   759 static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   760 {
   760 {
   761 	int32 ret, total_cost, signal_ctr;
   761 	CommandCost ret, total_cost;
       
   762 	int signal_ctr;
   762 	byte signals;
   763 	byte signals;
   763 	bool error = true;
   764 	bool error = true;
   764 	TileIndex end_tile;
   765 	TileIndex end_tile;
   765 
   766 
   766 	Track track = (Track)GB(p2, 0, 3);
   767 	Track track = (Track)GB(p2, 0, 3);
   813 			SB(p1, 3, 1, mode);
   814 			SB(p1, 3, 1, mode);
   814 			SB(p1, 4, 1, semaphores);
   815 			SB(p1, 4, 1, semaphores);
   815 			ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
   816 			ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
   816 
   817 
   817 			/* Be user-friendly and try placing signals as much as possible */
   818 			/* Be user-friendly and try placing signals as much as possible */
   818 			if (!CmdFailed(ret)) {
   819 			if (CmdSucceeded(ret)) {
   819 				error = false;
   820 				error = false;
   820 				total_cost += ret;
   821 				total_cost += ret;
   821 			}
   822 			}
   822 		}
   823 		}
   823 
   824 
   844  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
   845  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
   845  * - p2 = (bit  5)    - 0 = build, 1 = remove signals
   846  * - p2 = (bit  5)    - 0 = build, 1 = remove signals
   846  * - p2 = (bit 24-31) - user defined signals_density
   847  * - p2 = (bit 24-31) - user defined signals_density
   847  * @see CmdSignalTrackHelper
   848  * @see CmdSignalTrackHelper
   848  */
   849  */
   849 int32 CmdBuildSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   850 CommandCost CmdBuildSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   850 {
   851 {
   851 	return CmdSignalTrackHelper(tile, flags, p1, p2);
   852 	return CmdSignalTrackHelper(tile, flags, p1, p2);
   852 }
   853 }
   853 
   854 
   854 /** Remove signals
   855 /** Remove signals
   858  *           - (bit  0- 2) - track-orientation, valid values: 0-5 (Track enum)
   859  *           - (bit  0- 2) - track-orientation, valid values: 0-5 (Track enum)
   859  *           - (bit  3)    - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   860  *           - (bit  3)    - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   860  *           - (bit  4)    - 0 = signals, 1 = semaphores
   861  *           - (bit  4)    - 0 = signals, 1 = semaphores
   861  * @param p2 unused
   862  * @param p2 unused
   862  */
   863  */
   863 int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   864 CommandCost CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   864 {
   865 {
   865 	Track track = (Track)GB(p1, 0, 3);
   866 	Track track = (Track)GB(p1, 0, 3);
   866 
   867 
   867 	if (!ValParamTrackOrientation(track) ||
   868 	if (!ValParamTrackOrientation(track) ||
   868 			!IsTileType(tile, MP_RAILWAY) ||
   869 			!IsTileType(tile, MP_RAILWAY) ||
   907  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
   908  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
   908  * - p2 = (bit  5)    - 0 = build, 1 = remove signals
   909  * - p2 = (bit  5)    - 0 = build, 1 = remove signals
   909  * - p2 = (bit 24-31) - user defined signals_density
   910  * - p2 = (bit 24-31) - user defined signals_density
   910  * @see CmdSignalTrackHelper
   911  * @see CmdSignalTrackHelper
   911  */
   912  */
   912 int32 CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   913 CommandCost CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   913 {
   914 {
   914 	return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 5)); // bit 5 is remove bit
   915 	return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 5)); // bit 5 is remove bit
   915 }
   916 }
   916 
   917 
   917 typedef int32 DoConvertRailProc(TileIndex tile, RailType totype, bool exec);
   918 typedef CommandCost DoConvertRailProc(TileIndex tile, RailType totype, bool exec);
   918 
   919 
   919 /**
   920 /**
   920  * Switches the rail type.
   921  * Switches the rail type.
   921  * Railtypes are stored on a per-tile basis, not on a per-track basis, so
   922  * Railtypes are stored on a per-tile basis, not on a per-track basis, so
   922  * all the tracks in the given tile will be converted.
   923  * all the tracks in the given tile will be converted.
   924  * @param totype      The railtype we want to convert to
   925  * @param totype      The railtype we want to convert to
   925  * @param exec        Switches between test and execute mode
   926  * @param exec        Switches between test and execute mode
   926  * @return            The cost and state of the operation
   927  * @return            The cost and state of the operation
   927  * @retval CMD_ERROR  An error occured during the operation.
   928  * @retval CMD_ERROR  An error occured during the operation.
   928  */
   929  */
   929 static int32 DoConvertRail(TileIndex tile, RailType totype, bool exec)
   930 static CommandCost DoConvertRail(TileIndex tile, RailType totype, bool exec)
   930 {
   931 {
   931 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
   932 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
   932 
   933 
   933 	if (GetRailType(tile) == totype) return CMD_ERROR;
   934 	if (GetRailType(tile) == totype) return CMD_ERROR;
   934 
   935 
   964 	}
   965 	}
   965 
   966 
   966 	return _eco->GetPrice(CEconomy::PRICE_RAIL_BUILD) / 2;
   967 	return _eco->GetPrice(CEconomy::PRICE_RAIL_BUILD) / 2;
   967 }
   968 }
   968 
   969 
   969 extern int32 DoConvertStationRail(TileIndex tile, RailType totype, bool exec);
   970 extern CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec);
   970 extern int32 DoConvertStreetRail(TileIndex tile, RailType totype, bool exec);
   971 extern CommandCost DoConvertStreetRail(TileIndex tile, RailType totype, bool exec);
   971 extern int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec);
   972 extern CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec);
   972 
   973 
   973 /** Convert one rail type to the other. You can convert normal rail to
   974 /** Convert one rail type to the other. You can convert normal rail to
   974  * monorail/maglev easily or vice-versa.
   975  * monorail/maglev easily or vice-versa.
   975  * @param tile end tile of rail conversion drag
   976  * @param tile end tile of rail conversion drag
   976  * @param flags operation to perform
   977  * @param flags operation to perform
   977  * @param p1 start tile of drag
   978  * @param p1 start tile of drag
   978  * @param p2 new railtype to convert to
   979  * @param p2 new railtype to convert to
   979  */
   980  */
   980 int32 CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   981 CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   981 {
   982 {
   982 	int32 ret, cost, money;
   983 	CommandCost ret, cost;
       
   984 	int32 money;
   983 	int ex;
   985 	int ex;
   984 	int ey;
   986 	int ey;
   985 	int sx, sy, x, y;
   987 	int sx, sy, x, y;
   986 
   988 
   987 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   989 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
  1030 	}
  1032 	}
  1031 
  1033 
  1032 	return (cost == 0) ? ret : cost;
  1034 	return (cost == 0) ? ret : cost;
  1033 }
  1035 }
  1034 
  1036 
  1035 static int32 RemoveTrainDepot(TileIndex tile, uint32 flags)
  1037 static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags)
  1036 {
  1038 {
  1037 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
  1039 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
  1038 		return CMD_ERROR;
  1040 		return CMD_ERROR;
  1039 
  1041 
  1040 	if (!EnsureNoVehicleOnGround(tile))
  1042 	if (!EnsureNoVehicleOnGround(tile))
  1049 	}
  1051 	}
  1050 
  1052 
  1051 	return _eco->GetPrice(CEconomy::REMOVE_TRAIN_DEPOT, tile, true);
  1053 	return _eco->GetPrice(CEconomy::REMOVE_TRAIN_DEPOT, tile, true);
  1052 }
  1054 }
  1053 
  1055 
  1054 static int32 ClearTile_Track(TileIndex tile, byte flags)
  1056 static CommandCost ClearTile_Track(TileIndex tile, byte flags)
  1055 {
  1057 {
  1056 	int32 cost;
  1058 	CommandCost cost;
  1057 	int32 ret;
  1059 	CommandCost ret;
  1058 
  1060 
  1059 	if (flags & DC_AUTO) {
  1061 	if (flags & DC_AUTO) {
  1060 		if (!IsTileOwner(tile, _current_player))
  1062 		if (!IsTileOwner(tile, _current_player))
  1061 			return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER);
  1063 			return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER);
  1062 
  1064