mirror of https://github.com/OpenTTD/OpenTTD.git
(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
This commit is contained in:
parent
6bf62500ed
commit
a36f8a46fa
|
@ -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
|
||||
|
|
37
train_cmd.c
37
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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue