From a36f8a46faefa319720079aab6bc38cd272ccdb8 Mon Sep 17 00:00:00 2001 From: bjarni Date: Sat, 18 Mar 2006 13:00:32 +0000 Subject: [PATCH] (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 | 1 + train_cmd.c | 37 +++++++++++++++++++++++++++++++------ train_gui.c | 4 +++- vehicle.h | 3 +++ 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/lang/english.txt b/lang/english.txt index 5347a46a80..14682cd4b7 100644 --- a/lang/english.txt +++ b/lang/english.txt @@ -2530,6 +2530,7 @@ STR_9030_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT 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 diff --git a/train_cmd.c b/train_cmd.c index 7bff828047..b380893006 100644 --- a/train_cmd.c +++ b/train_cmd.c @@ -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 GetTrainImage(const Vehicle* v, Direction direction) 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 @@ static void ReverseTrainDirection(Vehicle *v) /** 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 @@ static void ReverseTrainDirection(Vehicle *v) 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 @@ static void HandleLocomotiveSmokeCloud(const Vehicle* v) 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. diff --git a/train_gui.c b/train_gui.c index 6325db403a..51565980b1 100644 --- a/train_gui.c +++ b/train_gui.c @@ -724,7 +724,9 @@ static void TrainDepotWndProc(Window *w, WindowEvent *e) 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); diff --git a/vehicle.h b/vehicle.h index 71e5c8c417..ecc2509634 100644 --- a/vehicle.h +++ b/vehicle.h @@ -88,6 +88,9 @@ enum { // 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 {