~ubuntu-branches/debian/squeeze/openttd/squeeze

« back to all changes in this revision

Viewing changes to src/train_cmd.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Matthijs Kooijman, Matthijs Kooijman
  • Date: 2009-10-01 22:52:59 UTC
  • mfrom: (1.1.8 upstream) (2.1.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091001225259-5kpkp4sthbszpyif
[ Matthijs Kooijman ]
* New upstream release
* Use printf instead of echo -en in openttd-wrapper to make it POSIX
  compatible (Closes: #547758).
* Remove three patches that are now included in upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: train_cmd.cpp 16482 2009-05-31 12:22:53Z rubidium $ */
 
1
/* $Id: train_cmd.cpp 17598 2009-09-21 15:41:58Z rubidium $ */
2
2
 
3
3
/** @file train_cmd.cpp Handling of trains. */
4
4
 
1061
1061
                                if (dst_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
1062
1062
                        }
1063
1063
 
 
1064
                        if (src_head == src && !HasBit(p2, 0)) {
 
1065
                                /* Moving of a *single* vehicle at the front of the train.
 
1066
                                 * If the next vehicle is an engine a new train will be created
 
1067
                                 * instead of removing a vehicle from a free chain. The newly
 
1068
                                 * created train may not be too long. */
 
1069
                                const Vehicle *u = GetNextVehicle(src_head);
 
1070
                                if (u != NULL && IsTrainEngine(u) && (src_len - 1) > max_len) return_cmd_error(STR_8819_TRAIN_TOO_LONG);
 
1071
                        }
 
1072
 
1064
1073
                        /* We are moving between rows, so only count the wagons from the source
1065
1074
                         * row that are being moved. */
1066
1075
                        if (HasBit(p2, 0)) {
1533
1542
        this->z_extent      = 6;
1534
1543
}
1535
1544
 
1536
 
static void UpdateVarsAfterSwap(Vehicle *v)
1537
 
{
1538
 
        v->UpdateDeltaXY(v->direction);
1539
 
        v->cur_image = v->GetImage(v->direction);
1540
 
        VehicleMove(v, true);
1541
 
}
1542
 
 
1543
1545
static inline void SetLastSpeed(Vehicle *v, int spd)
1544
1546
{
1545
1547
        int old = v->u.rail.last_speed;
1557
1559
        if (!HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
1558
1560
                /* It is the first time the problem occured, set the "train stuck" flag. */
1559
1561
                SetBit(v->u.rail.flags, VRF_TRAIN_STUCK);
 
1562
 
 
1563
                /* When loading the vehicle is already stopped. No need to change that. */
 
1564
                if (v->current_order.IsType(OT_LOADING)) return;
 
1565
 
1560
1566
                v->load_unload_time_rem = 0;
1561
1567
 
1562
1568
                /* Stop train */
1623
1629
                SwapTrainFlags(&a->u.rail.flags, &b->u.rail.flags);
1624
1630
 
1625
1631
                /* update other vars */
1626
 
                UpdateVarsAfterSwap(a);
1627
 
                UpdateVarsAfterSwap(b);
 
1632
                a->UpdateViewport(true, true);
 
1633
                b->UpdateViewport(true, true);
1628
1634
 
1629
1635
                /* call the proper EnterTile function unless we are in a wormhole */
1630
1636
                if (a->u.rail.track != TRACK_BIT_WORMHOLE) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
1631
1637
                if (b->u.rail.track != TRACK_BIT_WORMHOLE) VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
1632
1638
        } else {
1633
1639
                if (a->u.rail.track != TRACK_BIT_DEPOT) a->direction = ReverseDir(a->direction);
1634
 
                UpdateVarsAfterSwap(a);
 
1640
                a->UpdateViewport(true, true);
1635
1641
 
1636
1642
                if (a->u.rail.track != TRACK_BIT_WORMHOLE) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
1637
1643
        }
1824
1830
                InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
1825
1831
        }
1826
1832
 
1827
 
        /* Clear path reservation in front. */
1828
 
        FreeTrainTrackReservation(v);
 
1833
        /* Clear path reservation in front if train is not stuck. */
 
1834
        if (!HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) FreeTrainTrackReservation(v);
1829
1835
 
1830
1836
        /* Check if we were approaching a rail/road-crossing */
1831
1837
        TileIndex crossing = TrainApproachingCrossingTile(v);
1855
1861
        TrainConsistChanged(v, true);
1856
1862
 
1857
1863
        /* update all images */
1858
 
        for (Vehicle *u = v; u != NULL; u = u->Next()) u->cur_image = u->GetImage(u->direction);
 
1864
        for (Vehicle *u = v; u != NULL; u = u->Next()) u->UpdateViewport(false, false);
1859
1865
 
1860
1866
        /* update crossing we were approaching */
1861
1867
        if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
1917
1923
                /* turn a single unit around */
1918
1924
 
1919
1925
                if (IsMultiheaded(v) || HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) {
1920
 
                        return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
 
1926
                        return_cmd_error(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE_MULTIPLE_UNITS);
1921
1927
                }
1922
1928
 
1923
1929
                Vehicle *front = v->First();
2387
2393
        }
2388
2394
 
2389
2395
        /* We are leaving a depot, but have to go to the exact same one; re-enter */
2390
 
        if (v->tile == v->dest_tile) {
 
2396
        if (v->current_order.IsType(OT_GOTO_DEPOT) && v->tile == v->dest_tile) {
2391
2397
                /* We need to have a reservation for this to work. */
2392
2398
                if (GetDepotWaypointReservation(v->tile)) return true;
2393
2399
                SetDepotWaypointReservation(v->tile, true);
2708
2714
                }
2709
2715
 
2710
2716
                /* Station, depot or waypoint are a possible target. */
2711
 
                bool target_seen = ft.m_is_station || (IsTileType(ft.m_new_tile, MP_RAILWAY) && !IsPlainRailTile(ft.m_new_tile));
 
2717
                bool target_seen = ft.m_is_station || (IsTileType(ft.m_new_tile, MP_RAILWAY) && !IsPlainRail(ft.m_new_tile));
2712
2718
                if (target_seen || KillFirstBit(ft.m_new_td_bits) != TRACKDIR_BIT_NONE) {
2713
2719
                        /* Choice found or possible target encountered.
2714
2720
                         * On finding a possible target, we need to stop and let the pathfinder handle the
3082
3088
 
3083
3089
        bool other_train = false;
3084
3090
        PBSTileInfo origin = FollowTrainReservation(v, &other_train);
 
3091
        /* The path we are driving on is alread blocked by some other train.
 
3092
         * This can only happen in certain situations when mixing path and
 
3093
         * block signals or when changing tracks and/or signals.
 
3094
         * Exit here as doing any further reservations will probably just
 
3095
         * make matters worse. */
 
3096
        if (other_train && v->tile != origin.tile) {
 
3097
                if (mark_as_stuck) MarkTrainAsStuck(v);
 
3098
                return false;
 
3099
        }
3085
3100
        /* If we have a reserved path and the path ends at a safe tile, we are finished already. */
3086
3101
        if (origin.okay && (v->tile != origin.tile || first_tile_okay)) {
3087
3102
                /* Can't be stuck then. */
3089
3104
                ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
3090
3105
                return true;
3091
3106
        }
3092
 
        /* The path we are driving on is alread blocked by some other train.
3093
 
         * This can only happen when tracks and signals are changed. A crash
3094
 
         * is probably imminent, don't do any further reservation because
3095
 
         * it might cause stale reservations. */
3096
 
        if (other_train && v->tile != origin.tile) {
3097
 
                if (mark_as_stuck) MarkTrainAsStuck(v);
3098
 
                return false;
3099
 
        }
3100
3107
 
3101
3108
        /* If we are in a depot, tentativly reserve the depot. */
3102
3109
        if (v->u.rail.track & TRACK_BIT_DEPOT) {
3249
3256
{
3250
3257
        Vehicle *v = this;
3251
3258
        do {
3252
 
                v->cur_image = v->GetImage(v->direction);
3253
 
                MarkSingleVehicleDirty(v);
 
3259
                v->UpdateViewport(false, false);
3254
3260
        } while ((v = v->Next()) != NULL);
3255
3261
 
3256
3262
        /* need to update acceleration and cached values since the goods on the train changed. */
3474
3480
{
3475
3481
        if (v->u.rail.crash_anim_pos != 0) return;
3476
3482
 
3477
 
        /* Free a possible path reservation and try to mark all tiles occupied by the train reserved. */
3478
3483
        if (IsFrontEngine(v)) {
3479
 
                /* Remove all reservations, also the ones currently under the train
3480
 
                 * and any railway station paltform reservation. */
3481
 
                FreeTrainTrackReservation(v);
 
3484
                /* Remove the reserved path in front of the train if it is not stuck.
 
3485
                 * Also clear all reserved tracks the train is currently on. */
 
3486
                if (!HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) FreeTrainTrackReservation(v);
3482
3487
                for (const Vehicle *u = v; u != NULL; u = u->Next()) {
3483
3488
                        ClearPathReservation(u, u->tile, GetVehicleTrackdir(u));
3484
3489
                        if (IsTileType(u->tile, MP_TUNNELBRIDGE)) {
4052
4057
 
4053
4058
                InvalidateWindow(WC_VEHICLE_VIEW, v->index);
4054
4059
                InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
4060
                v->MarkDirty();
4055
4061
 
4056
4062
                if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
4057
4063
                        SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
4068
4074
                if (!--v->breakdown_delay) {
4069
4075
                        v->breakdown_ctr = 0;
4070
4076
                        InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
4077
                        v->MarkDirty();
4071
4078
                }
4072
4079
        }
4073
4080
}
4365
4372
        for (Vehicle *u = v; u != NULL; u = u->Next()) {
4366
4373
                if ((u->vehstatus & VS_HIDDEN) != 0) continue;
4367
4374
 
4368
 
                uint16 old_image = u->cur_image;
4369
 
                u->cur_image = u->GetImage(u->direction);
4370
 
                if (old_image != u->cur_image) VehicleMove(u, true);
 
4375
                u->UpdateViewport(false, false);
4371
4376
        }
4372
4377
 
4373
4378
        if (v->progress == 0) v->progress = j; // Save unused spd for next time, if TrainController didn't set progress