summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2006-01-25 21:33:57 +0000
committerpeter1138 <peter1138@openttd.org>2006-01-25 21:33:57 +0000
commit952f246433f8f515b2bba70c6f43071e4416afb8 (patch)
treeb3122ca683accbc503b61c6692430ea870a89f6c
parenta8758cbf5e2e80ae8ca96163acf57bcc2d3df6f5 (diff)
downloadopenttd-952f246433f8f515b2bba70c6f43071e4416afb8.tar.xz
(svn r3431) - Fix crash when moving vehicles around in a train depot under certain conditions.
-rw-r--r--train_cmd.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/train_cmd.c b/train_cmd.c
index 114741b23..4b77368cc 100644
--- a/train_cmd.c
+++ b/train_cmd.c
@@ -994,47 +994,53 @@ int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if (IsMultiheaded(src) && !IsTrainEngine(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
+ // when moving all wagons, we can't have the same src_head and dst_head
+ if (HASBIT(p2, 0) && src_head == dst_head) return 0;
+
{
- int r, num = 0;
+ int src_len = 0;
+ int max_len = _patches.mammoth_trains ? 100 : 9;
- r = CheckTrainStoppedInDepot(src_head);
- /* check if all vehicles in the source train are stopped inside a depot */
- if (r < 0) return CMD_ERROR;
+ // check if all vehicles in the source train are stopped inside a depot.
+ src_len = CheckTrainStoppedInDepot(src_head);
+ if (src_len < 0) return CMD_ERROR;
- if (HASBIT(p2, 0)) {
- /* If moving the rest of the train, exclude wagons before the
- * selected one. */
+ // check the destination row if the source and destination aren't the same.
+ if (src_head != dst_head) {
+ int dst_len = 0;
- Vehicle *u;
- for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u))
- r--;
+ if (dst_head != NULL) {
+ // check if all vehicles in the dest train are stopped.
+ dst_len = CheckTrainStoppedInDepot(dst_head);
+ if (dst_len < 0) return CMD_ERROR;
- num += r;
- } else {
- // If moving only one vehicle, just count that.
- num++;
- }
-
- /* check if all the vehicles in the dest train are stopped */
- if (dst_head != NULL) {
- r = CheckTrainStoppedInDepot(dst_head);
- if (r < 0) return CMD_ERROR;
+ assert(dst_head->tile == src_head->tile);
+ }
- /* If we move in the same vehicle, it is okay */
- if (dst_head != src_head)
- num += r;
+ // We are moving between rows, so only count the wagons from the source
+ // row that are being moved.
+ if (HASBIT(p2, 0)) {
+ const Vehicle *u;
+ for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u))
+ src_len--;
+ } else {
+ // If moving only one vehicle, just count that.
+ src_len = 1;
+ }
- assert(dst_head->tile == src_head->tile);
+ if (src_len + dst_len > max_len) {
+ // Abort if we're adding too many wagons to a train.
+ if (dst_head != NULL && IsFrontEngine(dst_head)) return_cmd_error(STR_8819_TRAIN_TOO_LONG);
+ // Abort if we're making a train on a new row.
+ if (dst_head == NULL && IsTrainEngine(src)) return_cmd_error(STR_8819_TRAIN_TOO_LONG);
+ }
+ } else {
+ // Abort if we're creating a new train on an existing row.
+ if (src_len > max_len && src == src_head && IsTrainEngine(GetNextVehicle(src_head)))
+ return_cmd_error(STR_8819_TRAIN_TOO_LONG);
}
-
- /* Check that the length of the dest train is no longer than XXX vehicles */
- if (num > (_patches.mammoth_trains ? 100 : 9) && IsFrontEngine(dst_head))
- return_cmd_error(STR_8819_TRAIN_TOO_LONG);
}
- // when moving all wagons, we can't have the same src_head and dst_head
- if (HASBIT(p2, 0) && src_head == dst_head) return 0;
-
// moving a loco to a new line?, then we need to assign a unitnumber.
if (dst == NULL && !IsFrontEngine(src) && IsTrainEngine(src)) {
UnitID unit_num = GetFreeUnitNumber(VEH_Train);