(svn r3944) -Feature: it's now possible to turn a single unit in a train
authorbjarni
Sat, 18 Mar 2006 13:00:32 +0000
changeset 3256 a23d94f568b7
parent 3255 95d5afbe2634
child 3257 aed8705e3847
(svn r3944) -Feature: it's now possible to turn a single unit in a train
control-click on a unit in a train in a depot will make the click unit turn around
this is useful if you want "normal" engines to act as dualheaded (one each way) or similar
this only works on single unit units. Multiheaded and articulated engines get a red error box
this is based on a quick hack peter1138 while I made it network safe and correctly handling of multible unit engines
lang/english.txt
train_cmd.c
train_gui.c
vehicle.h
--- a/lang/english.txt	Sat Mar 18 12:16:50 2006 +0000
+++ b/lang/english.txt	Sat Mar 18 13:00:32 2006 +0000
@@ -2530,6 +2530,7 @@
 STR_9031_ROAD_VEHICLE_CRASH_DRIVER                              :{BLACK}{BIGFONT}Road Vehicle Crash!{}Driver dies in fireball after collision with train
 STR_9032_ROAD_VEHICLE_CRASH_DIE                                 :{BLACK}{BIGFONT}Road Vehicle Crash!{}{COMMA} die in fireball after collision with train
 STR_9033_CAN_T_MAKE_VEHICLE_TURN                                :{WHITE}Can't make vehicle turn around...
+STR_ONLY_TURN_SINGLE_UNIT                                       :{WHITE}Can't turn vehicles consisting of multiple units
 STR_9034_RENAME                                                 :{BLACK}Rename
 STR_9035_RENAME_ROAD_VEHICLE_TYPE                               :{BLACK}Rename road vehicle type
 STR_9036_RENAME_ROAD_VEHICLE_TYPE                               :{WHITE}Rename road vehicle type
--- a/train_cmd.c	Sat Mar 18 12:16:50 2006 +0000
+++ b/train_cmd.c	Sat Mar 18 13:00:32 2006 +0000
@@ -26,6 +26,7 @@
 #include "train.h"
 #include "newgrf_callbacks.h"
 #include "newgrf_engine.h"
+#include "direction.h"
 
 static bool TrainCheckIfLineEnds(Vehicle *v);
 static void TrainController(Vehicle *v);
@@ -379,6 +380,8 @@
 	int img = v->spritenum;
 	int base;
 
+	if (HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
+
 	if (is_custom_sprite(img)) {
 		base = GetCustomVehicleSprite(v, direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img));
 		if (base != 0) return base;
@@ -1579,7 +1582,7 @@
 /** Reverse train.
  * @param x,y unused
  * @param p1 train to reverse
- * @param p2 unused
+ * @param p2 if true, reverse a unit in a train (needs to be in a depot)
  */
  int32 CmdReverseTrainDirection(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 {
@@ -1591,18 +1594,35 @@
 
 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
 
+	if (p2) {
+		Vehicle *front;
+
+		if (IsMultiheaded(v) || HASBIT(RailVehInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) {
+			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
+		}
+
+		front = GetFirstVehicleInChain(v);
+		// make sure the vehicle is stopped in the depot
+		if (CheckTrainStoppedInDepot(front) < 0) {
+			return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
+		}
+	}
 //	if (v->u.rail.track & 0x80 || IsTileDepotType(v->tile, TRANSPORT_RAIL))
 //		return CMD_ERROR;
 
 	if (v->u.rail.crash_anim_pos != 0 || v->breakdown_ctr != 0) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
-		if (_patches.realistic_acceleration && v->cur_speed != 0) {
-			TOGGLEBIT(v->u.rail.flags, VRF_REVERSING);
+		if (p2) {
+			v->u.rail.flags ^= 1 << VRF_REVERSE_DIRECTION;
 		} else {
-			v->cur_speed = 0;
-			SetLastSpeed(v, 0);
-			ReverseTrainDirection(v);
+			if (_patches.realistic_acceleration && v->cur_speed != 0) {
+				TOGGLEBIT(v->u.rail.flags, VRF_REVERSING);
+			} else {
+				v->cur_speed = 0;
+				SetLastSpeed(v, 0);
+				ReverseTrainDirection(v);
+			}
 		}
 	}
 	return 0;
@@ -1898,6 +1918,11 @@
 		x = _vehicle_smoke_pos[v->direction] * effect_offset;
 		y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
 
+		if (HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
+			x = -x;
+			y = -y;
+		}
+
 		switch (effect_type) {
 		case 0:
 			// steam smoke.
--- a/train_gui.c	Sat Mar 18 12:16:50 2006 +0000
+++ b/train_gui.c	Sat Mar 18 13:00:32 2006 +0000
@@ -724,7 +724,9 @@
 
 				if (GetVehicleFromTrainDepotWndPt(w, e->dragdrop.pt.x, e->dragdrop.pt.y, &gdvp) == 0 &&
 						sel != INVALID_VEHICLE) {
-					if (gdvp.wagon == NULL || gdvp.wagon->index != sel) {
+					if (gdvp.wagon != NULL && gdvp.wagon->index == sel && _ctrl_pressed) {
+						DoCommandP(GetVehicle(sel)->tile, GetVehicle(sel)->index, true, NULL, CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_9033_CAN_T_MAKE_VEHICLE_TURN));
+					} else if (gdvp.wagon == NULL || gdvp.wagon->index != sel) {
 						TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head);
 					} else if (gdvp.head != NULL && IsFrontEngine(gdvp.head)) {
 						ShowTrainViewWindow(gdvp.head);
--- a/vehicle.h	Sat Mar 18 12:16:50 2006 +0000
+++ b/vehicle.h	Sat Mar 18 13:00:32 2006 +0000
@@ -88,6 +88,9 @@
 
 	// used to store if a wagon is powered or not
 	VRF_POWEREDWAGON = 3,
+
+	// used to reverse the visible direction of the vehicle
+	VRF_REVERSE_DIRECTION = 4,
 };
 
 typedef struct VehicleAir {