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

« back to all changes in this revision

Viewing changes to src/ship_cmd.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jordi Mallach, Matthijs Kooijman, Jordi Mallach
  • Date: 2009-04-15 18:22:10 UTC
  • mfrom: (1.1.6 upstream) (2.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090415182210-22ktb8kdbp2tf3bm
[ Matthijs Kooijman ]
* New upstream release.
* Remove Debian specific desktop file, upstream provides one now. 
* Add debian/watch file.

[ Jordi Mallach ]
* Bump Standards-Version to 3.8.1, with no changes required.
* Move to debhelper compat 7. Bump Build-Depends accordingly.
* Use dh_prep.
* Add "set -e" to config script.
* Remove a few extra doc files that get installed by upstream Makefile.
* Add more complete copyright information.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: ship_cmd.cpp 13708 2008-07-16 10:07:38Z rubidium $ */
 
1
/* $Id: ship_cmd.cpp 15718 2009-03-15 00:32:18Z rubidium $ */
2
2
 
3
 
/** @file ship_cmd.cpp */
 
3
/** @file ship_cmd.cpp Handling of ships. */
4
4
 
5
5
#include "stdafx.h"
6
 
#include "openttd.h"
7
6
#include "ship.h"
8
 
#include "tile_cmd.h"
9
7
#include "landscape.h"
10
8
#include "timetable.h"
11
9
#include "command_func.h"
12
 
#include "pathfind.h"
13
10
#include "station_map.h"
14
 
#include "station.h"
15
 
#include "news.h"
16
 
#include "engine.h"
17
 
#include "player_func.h"
18
 
#include "player_base.h"
 
11
#include "news_func.h"
 
12
#include "company_func.h"
19
13
#include "npf.h"
20
 
#include "depot.h"
 
14
#include "depot_base.h"
21
15
#include "vehicle_gui.h"
22
16
#include "newgrf_engine.h"
23
 
#include "water_map.h"
24
17
#include "yapf/yapf.h"
25
 
#include "debug.h"
26
 
#include "newgrf_callbacks.h"
27
 
#include "newgrf_text.h"
28
18
#include "newgrf_sound.h"
29
19
#include "spritecache.h"
30
20
#include "strings_func.h"
36
26
#include "variables.h"
37
27
#include "autoreplace_gui.h"
38
28
#include "gfx_func.h"
 
29
#include "effectvehicle_func.h"
39
30
#include "settings_type.h"
 
31
#include "ai/ai.hpp"
 
32
#include "pathfind.h"
40
33
 
41
34
#include "table/strings.h"
 
35
#include "table/sprites.h"
42
36
 
43
37
static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
44
38
 
54
48
        return TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0));
55
49
}
56
50
 
 
51
static SpriteID GetShipIcon(EngineID engine)
 
52
{
 
53
        uint8 spritenum = ShipVehInfo(engine)->image_index;
 
54
 
 
55
        if (is_custom_sprite(spritenum)) {
 
56
                SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W);
 
57
                if (sprite != 0) return sprite;
 
58
 
 
59
                spritenum = GetEngine(engine)->image_index;
 
60
        }
 
61
 
 
62
        return 6 + _ship_sprites[spritenum];
 
63
}
 
64
 
57
65
void DrawShipEngine(int x, int y, EngineID engine, SpriteID pal)
58
66
{
59
 
        int spritenum = ShipVehInfo(engine)->image_index;
60
 
 
61
 
        if (is_custom_sprite(spritenum)) {
62
 
                int sprite = GetCustomVehicleIcon(engine, DIR_W);
63
 
 
64
 
                if (sprite != 0) {
65
 
                        DrawSprite(sprite, pal, x, y);
66
 
                        return;
67
 
                }
68
 
                spritenum = _orig_ship_vehicle_info[engine - SHIP_ENGINES_INDEX].image_index;
69
 
        }
70
 
        DrawSprite(6 + _ship_sprites[spritenum], pal, x, y);
 
67
        DrawSprite(GetShipIcon(engine), pal, x, y);
71
68
}
72
69
 
73
70
/** Get the size of the sprite of a ship sprite heading west (used for lists)
77
74
 */
78
75
void GetShipSpriteSize(EngineID engine, uint &width, uint &height)
79
76
{
80
 
        SpriteID spritenum = ShipVehInfo(engine)->image_index;
81
 
        SpriteID custom_sprite = 0;
82
 
 
83
 
        if (is_custom_sprite(spritenum)) {
84
 
                custom_sprite = GetCustomVehicleIcon(engine, DIR_W);
85
 
                spritenum = _orig_ship_vehicle_info[engine - SHIP_ENGINES_INDEX].image_index;
86
 
        }
87
 
        if (custom_sprite == 0) {
88
 
                spritenum = 6 + _ship_sprites[spritenum];
89
 
        } else {
90
 
                spritenum = custom_sprite;
91
 
        }
92
 
 
93
 
        const Sprite *spr = GetSprite(spritenum);
 
77
        const Sprite *spr = GetSprite(GetShipIcon(engine), ST_NORMAL);
94
78
 
95
79
        width  = spr->width;
96
80
        height = spr->height;
97
81
}
98
82
 
99
 
int Ship::GetImage(Direction direction) const
 
83
SpriteID Ship::GetImage(Direction direction) const
100
84
{
101
 
        int spritenum = this->spritenum;
 
85
        uint8 spritenum = this->spritenum;
102
86
 
103
87
        if (is_custom_sprite(spritenum)) {
104
 
                int sprite = GetCustomVehicleSprite(this, direction);
105
 
 
 
88
                SpriteID sprite = GetCustomVehicleSprite(this, direction);
106
89
                if (sprite != 0) return sprite;
107
 
                spritenum = _orig_ship_vehicle_info[this->engine_type - SHIP_ENGINES_INDEX].image_index;
 
90
 
 
91
                spritenum = GetEngine(this->engine_type)->image_index;
108
92
        }
 
93
 
109
94
        return _ship_sprites[spritenum] + direction;
110
95
}
111
96
 
112
 
static const Depot* FindClosestShipDepot(const Vehicle* v)
 
97
static const Depot *FindClosestShipDepot(const Vehicle *v)
113
98
{
114
 
        if (_patches.pathfinder_for_ships == VPF_NPF) { /* NPF is used */
 
99
        if (_settings_game.pf.pathfinder_for_ships == VPF_NPF) { // NPF is used
115
100
                Trackdir trackdir = GetVehicleTrackdir(v);
116
101
                NPFFoundTargetData ftd = NPFRouteToDepotTrialError(v->tile, trackdir, false, TRANSPORT_WATER, 0, v->owner, INVALID_RAILTYPES);
117
102
 
118
 
                if (ftd.best_bird_dist == 0) return GetDepotByTile(ftd.node.tile); /* Found target */
 
103
                if (ftd.best_bird_dist == 0) return GetDepotByTile(ftd.node.tile); // Found target
119
104
 
120
 
                return NULL; /* Did not find target */
 
105
                return NULL; // Did not find target
121
106
        }
122
107
 
123
108
        /* OPF or YAPF - find the closest depot */
124
109
 
125
 
        const Depot* depot;
126
 
        const Depot* best_depot = NULL;
 
110
        const Depot *depot;
 
111
        const Depot *best_depot = NULL;
127
112
        uint best_dist = UINT_MAX;
128
113
 
129
114
        FOR_ALL_DEPOTS(depot) {
130
115
                TileIndex tile = depot->xy;
131
 
                if (IsTileDepotType(tile, TRANSPORT_WATER) && IsTileOwner(tile, v->owner)) {
 
116
                if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) {
132
117
                        uint dist = DistanceManhattan(tile, v->tile);
133
118
                        if (dist < best_dist) {
134
119
                                best_dist = dist;
142
127
 
143
128
static void CheckIfShipNeedsService(Vehicle *v)
144
129
{
145
 
        if (_patches.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
 
130
        if (_settings_game.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
146
131
        if (v->IsInDepot()) {
147
132
                VehicleServiceInDepot(v);
148
133
                return;
151
136
        const Depot *depot = FindClosestShipDepot(v);
152
137
 
153
138
        if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) {
154
 
                if (v->current_order.type == OT_GOTO_DEPOT) {
155
 
                        v->current_order.type = OT_DUMMY;
156
 
                        v->current_order.flags = 0;
 
139
                if (v->current_order.IsType(OT_GOTO_DEPOT)) {
 
140
                        v->current_order.MakeDummy();
157
141
                        InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
158
142
                }
159
143
                return;
160
144
        }
161
145
 
162
 
        v->current_order.type = OT_GOTO_DEPOT;
163
 
        v->current_order.flags = OFB_NON_STOP;
164
 
        v->current_order.dest = depot->index;
 
146
        v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE);
165
147
        v->dest_tile = depot->xy;
166
148
        InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
167
149
}
168
150
 
 
151
Money Ship::GetRunningCost() const
 
152
{
 
153
        return GetVehicleProperty(this, 0x0F, ShipVehInfo(this->engine_type)->running_cost) * _price.ship_running;
 
154
}
 
155
 
169
156
void Ship::OnNewDay()
170
157
{
171
158
        if ((++this->day_counter & 7) == 0)
179
166
 
180
167
        if (this->running_ticks == 0) return;
181
168
 
182
 
        CommandCost cost(EXPENSES_SHIP_RUN, GetVehicleProperty(this, 0x0F, ShipVehInfo(this->engine_type)->running_cost) * _price.ship_running * this->running_ticks / (364 * DAY_TICKS));
 
169
        CommandCost cost(EXPENSES_SHIP_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS));
183
170
 
184
171
        this->profit_this_year -= cost.GetCost();
185
172
        this->running_ticks = 0;
186
173
 
187
 
        SubtractMoneyFromPlayerFract(this->owner, cost);
 
174
        SubtractMoneyFromCompanyFract(this->owner, cost);
188
175
 
189
176
        InvalidateWindow(WC_VEHICLE_DETAILS, this->index);
190
177
        /* we need this for the profit */
204
191
                InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
205
192
 
206
193
                if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
207
 
                        SndPlayVehicleFx((_opt.landscape != LT_TOYLAND) ?
 
194
                        SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
208
195
                                SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
209
196
                }
210
197
 
211
198
                if (!(v->vehstatus & VS_HIDDEN)) {
212
199
                        Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
213
 
                        if (u != NULL) u->u.special.animation_state = v->breakdown_delay * 2;
 
200
                        if (u != NULL) u->u.effect.animation_state = v->breakdown_delay * 2;
214
201
                }
215
202
        }
216
203
 
240
227
        PlayShipSound(this);
241
228
}
242
229
 
243
 
static void ProcessShipOrder(Vehicle *v)
 
230
TileIndex Ship::GetOrderStationLocation(StationID station)
244
231
{
245
 
        const Order *order;
246
 
 
247
 
        switch (v->current_order.type) {
248
 
                case OT_GOTO_DEPOT:
249
 
                        if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return;
250
 
                        if (v->current_order.flags & OFB_SERVICE_IF_NEEDED &&
251
 
                                        !v->NeedsServicing()) {
252
 
                                UpdateVehicleTimetable(v, true);
253
 
                                v->cur_order_index++;
254
 
                        }
255
 
                        break;
256
 
 
257
 
                case OT_LOADING:
258
 
                case OT_LEAVESTATION:
259
 
                        return;
260
 
 
261
 
                default: break;
262
 
        }
263
 
 
264
 
        if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
265
 
 
266
 
        order = GetVehicleOrder(v, v->cur_order_index);
267
 
 
268
 
        if (order == NULL) {
269
 
                v->current_order.Free();
270
 
                v->dest_tile = 0;
271
 
                return;
272
 
        }
273
 
 
274
 
        if (order->type  == v->current_order.type &&
275
 
                        order->flags == v->current_order.flags &&
276
 
                        order->dest  == v->current_order.dest &&
277
 
                        (order->type != OT_GOTO_STATION || GetStation(order->dest)->dock_tile != 0))
278
 
                return;
279
 
 
280
 
        v->current_order = *order;
281
 
 
282
 
        if (order->type == OT_GOTO_STATION) {
283
 
                const Station *st;
284
 
 
285
 
                if (order->dest == v->last_station_visited)
286
 
                        v->last_station_visited = INVALID_STATION;
287
 
 
288
 
                st = GetStation(order->dest);
289
 
                if (st->dock_tile != 0) {
290
 
                        v->dest_tile = TILE_ADD(st->dock_tile, ToTileIndexDiff(GetDockOffset(st->dock_tile)));
291
 
                } else {
292
 
                        v->cur_order_index++;
293
 
                }
294
 
        } else if (order->type == OT_GOTO_DEPOT) {
295
 
                v->dest_tile = GetDepot(order->dest)->xy;
 
232
        if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
 
233
 
 
234
        const Station *st = GetStation(station);
 
235
        if (st->dock_tile != INVALID_TILE) {
 
236
                return TILE_ADD(st->dock_tile, ToTileIndexDiff(GetDockOffset(st->dock_tile)));
296
237
        } else {
297
 
                v->dest_tile = 0;
 
238
                this->cur_order_index++;
 
239
                return 0;
298
240
        }
299
 
 
300
 
        InvalidateVehicleOrder(v);
301
 
 
302
 
        InvalidateWindowClasses(WC_SHIPS_LIST);
303
241
}
304
242
 
305
243
void Ship::UpdateDeltaXY(Direction direction)
320
258
        uint32 x = _delta_xy_table[direction];
321
259
        this->x_offs        = GB(x,  0, 8);
322
260
        this->y_offs        = GB(x,  8, 8);
323
 
        this->sprite_width  = GB(x, 16, 8);
324
 
        this->sprite_height = GB(x, 24, 8);
325
 
        this->z_height      = 6;
 
261
        this->x_extent      = GB(x, 16, 8);
 
262
        this->y_extent      = GB(x, 24, 8);
 
263
        this->z_extent      = 6;
326
264
}
327
265
 
328
266
void RecalcShipStuff(Vehicle *v)
340
278
 
341
279
static void CheckShipLeaveDepot(Vehicle *v)
342
280
{
343
 
        TileIndex tile;
344
 
        Axis axis;
345
 
        uint m;
346
 
 
347
281
        if (!v->IsInDepot()) return;
348
282
 
349
 
        tile = v->tile;
350
 
        axis = GetShipDepotAxis(tile);
 
283
        TileIndex tile = v->tile;
 
284
        Axis axis = GetShipDepotAxis(tile);
351
285
 
352
 
        /* Check first side */
 
286
        /* Check first (north) side */
353
287
        if (_ship_sometracks[axis] & GetTileShipTrackStatus(TILE_ADD(tile, ToTileIndexDiff(_ship_leave_depot_offs[axis])))) {
354
 
                m = (axis == AXIS_X) ? 0x101 : 0x207;
355
 
        /* Check second side */
 
288
                v->direction = ReverseDir(AxisToDirection(axis));
 
289
        /* Check second (south) side */
356
290
        } else if (_ship_sometracks[axis + 2] & GetTileShipTrackStatus(TILE_ADD(tile, -2 * ToTileIndexDiff(_ship_leave_depot_offs[axis])))) {
357
 
                m = (axis == AXIS_X) ? 0x105 : 0x203;
 
291
                v->direction = AxisToDirection(axis);
358
292
        } else {
359
293
                return;
360
294
        }
361
 
        v->direction    = (Direction)GB(m, 0, 8);
362
 
        v->u.ship.state = (TrackBits)GB(m, 8, 8);
 
295
 
 
296
        v->u.ship.state = AxisToTrackBits(axis);
363
297
        v->vehstatus &= ~VS_HIDDEN;
364
298
 
365
299
        v->cur_speed = 0;
378
312
 
379
313
        spd = min(v->cur_speed + 1, GetVehicleProperty(v, 0x0B, v->max_speed));
380
314
 
381
 
        /*updates statusbar only if speed have changed to save CPU time */
 
315
        /* updates statusbar only if speed have changed to save CPU time */
382
316
        if (spd != v->cur_speed) {
383
317
                v->cur_speed = spd;
384
 
                if (_patches.vehicle_speed)
 
318
                if (_settings_client.gui.vehicle_speed)
385
319
                        InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
386
320
        }
387
321
 
396
330
        return (t < v->progress);
397
331
}
398
332
 
399
 
static CommandCost EstimateShipCost(EngineID engine_type)
400
 
{
401
 
        return CommandCost(EXPENSES_NEW_VEHICLES, GetEngineProperty(engine_type, 0x0A, ShipVehInfo(engine_type)->base_cost) * (_price.ship_base >> 3) >> 5);
402
 
}
403
 
 
404
 
static void ShipArrivesAt(const Vehicle* v, Station* st)
 
333
static void ShipArrivesAt(const Vehicle *v, Station *st)
405
334
{
406
335
        /* Check if station was ever visited before */
407
336
        if (!(st->had_vehicle_of_type & HVOT_SHIP)) {
408
 
                uint32 flags;
409
 
 
410
337
                st->had_vehicle_of_type |= HVOT_SHIP;
411
338
 
412
339
                SetDParam(0, st->index);
413
 
                flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0);
414
340
                AddNewsItem(
415
341
                        STR_9833_CITIZENS_CELEBRATE_FIRST,
416
 
                        flags,
 
342
                        (v->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER,
417
343
                        v->index,
418
 
                        0);
 
344
                        st->index
 
345
                );
 
346
                AI::NewEvent(v->owner, new AIEventStationFirstVehicle(st->index, v->index));
419
347
        }
420
348
}
421
349
 
472
400
        do {
473
401
                i = RemoveFirstTrack(&bits);
474
402
 
475
 
                pfs.best_bird_dist = (uint)-1;
476
 
                pfs.best_length = (uint)-1;
 
403
                pfs.best_bird_dist = UINT_MAX;
 
404
                pfs.best_length = UINT_MAX;
477
405
 
478
 
                FollowTrack(tile, 0x1800 | TRANSPORT_WATER, 0, (DiagDirection)_ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs);
 
406
                FollowTrack(tile, PATHFIND_FLAGS_SHIP_MODE | PATHFIND_FLAGS_DISABLE_TILE_HASH, TRANSPORT_WATER, 0, (DiagDirection)_ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs);
479
407
 
480
408
                if (best_track != INVALID_TRACK) {
481
409
                        if (pfs.best_bird_dist != 0) {
506
434
        return best_bird_dist;
507
435
}
508
436
 
509
 
static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, bool ignore_start_tile, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypes railtypes)
 
437
static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, bool ignore_start_tile, NPFFindStationOrTileData *target, TransportType type, Owner owner, RailTypes railtypes)
510
438
{
511
439
 
512
 
        void* perf = NpfBeginInterval();
 
440
        void *perf = NpfBeginInterval();
513
441
        NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, ignore_start_tile, target, type, 0, owner, railtypes);
514
442
        int t = NpfEndInterval(perf);
515
443
        DEBUG(yapf, 4, "[NPFW] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
523
451
{
524
452
        assert(IsValidDiagDirection(enterdir));
525
453
 
526
 
        switch (_patches.pathfinder_for_ships) {
527
 
                case VPF_YAPF: { /* YAPF */
 
454
        switch (_settings_game.pf.pathfinder_for_ships) {
 
455
                case VPF_YAPF: { // YAPF
528
456
                        Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks);
529
457
                        if (trackdir != INVALID_TRACKDIR) return TrackdirToTrack(trackdir);
530
458
                } break;
531
459
 
532
 
                case VPF_NPF: { /* NPF */
 
460
                case VPF_NPF: { // NPF
533
461
                        NPFFindStationOrTileData fstd;
534
462
                        Trackdir trackdir = GetVehicleTrackdir(v);
535
463
                        assert(trackdir != INVALID_TRACKDIR); // Check that we are not in a depot
542
470
                         * the direction we need to take to get there, if ftd.best_bird_dist is not 0,
543
471
                         * we did not find our target, but ftd.best_trackdir contains the direction leading
544
472
                         * to the tile closest to our target. */
545
 
                        if (ftd.best_trackdir != 0xff) return TrackdirToTrack(ftd.best_trackdir); /* TODO: Wrapper function? */
 
473
                        if (ftd.best_trackdir != 0xff) return TrackdirToTrack(ftd.best_trackdir); // TODO: Wrapper function?
546
474
                } break;
547
475
 
548
476
                default:
549
 
                case VPF_OPF: { /* OPF */
 
477
                case VPF_OPF: { // OPF
550
478
                        TileIndex tile2 = TILE_ADD(tile, -TileOffsByDiagDir(enterdir));
551
479
                        Track track;
552
480
 
566
494
                } break;
567
495
        }
568
496
 
569
 
        return INVALID_TRACK; /* We could better reverse */
 
497
        return INVALID_TRACK; // We could better reverse
570
498
}
571
499
 
572
500
static const Direction _new_vehicle_direction_table[] = {
646
574
                        HandleBrokenShip(v);
647
575
                        return;
648
576
                }
649
 
                if (v->current_order.type != OT_LOADING) v->breakdown_ctr--;
 
577
                if (!v->current_order.IsType(OT_LOADING)) v->breakdown_ctr--;
650
578
        }
651
579
 
652
580
        if (v->vehstatus & VS_STOPPED) return;
653
581
 
654
 
        ProcessShipOrder(v);
 
582
        ProcessOrders(v);
655
583
        v->HandleLoading();
656
584
 
657
 
        if (v->current_order.type == OT_LOADING) return;
 
585
        if (v->current_order.IsType(OT_LOADING)) return;
658
586
 
659
587
        CheckShipLeaveDepot(v);
660
588
 
661
589
        if (!ShipAccelerate(v)) return;
662
590
 
663
 
        BeginVehicleMove(v);
664
 
 
665
591
        GetNewVehiclePosResult gp = GetNewVehiclePos(v);
666
 
        if (gp.old_tile == gp.new_tile) {
667
 
                /* Staying in tile */
668
 
                if (v->IsInDepot()) {
669
 
                        gp.x = v->x_pos;
670
 
                        gp.y = v->y_pos;
671
 
                } else {
672
 
                        /* Not inside depot */
673
 
                        r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
674
 
                        if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
675
 
 
676
 
                        /* A leave station order only needs one tick to get processed, so we can
677
 
                         * always skip ahead. */
678
 
                        if (v->current_order.type == OT_LEAVESTATION) {
679
 
                                v->current_order.Free();
680
 
                                InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
681
 
                        } else if (v->dest_tile != 0) {
682
 
                                /* We have a target, let's see if we reached it... */
683
 
                                if (v->current_order.type == OT_GOTO_STATION &&
684
 
                                                IsBuoyTile(v->dest_tile) &&
685
 
                                                DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
686
 
                                        /* We got within 3 tiles of our target buoy, so let's skip to our
687
 
                                         * next order */
688
 
                                        UpdateVehicleTimetable(v, true);
689
 
                                        v->cur_order_index++;
690
 
                                        v->current_order.type = OT_DUMMY;
691
 
                                        InvalidateVehicleOrder(v);
692
 
                                } else {
693
 
                                        /* Non-buoy orders really need to reach the tile */
694
 
                                        if (v->dest_tile == gp.new_tile) {
695
 
                                                if (v->current_order.type == OT_GOTO_DEPOT) {
696
 
                                                        if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) {
697
 
                                                                VehicleEnterDepot(v);
698
 
                                                                return;
699
 
                                                        }
700
 
                                                } else if (v->current_order.type == OT_GOTO_STATION) {
701
 
                                                        Station *st;
702
 
 
703
 
                                                        v->last_station_visited = v->current_order.dest;
704
 
 
705
 
                                                        /* Process station in the orderlist. */
706
 
                                                        st = GetStation(v->current_order.dest);
707
 
                                                        if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
708
 
                                                                ShipArrivesAt(v, st);
709
 
                                                                v->BeginLoading();
710
 
                                                        } else { // leave stations without docks right aways
711
 
                                                                v->current_order.type = OT_LEAVESTATION;
712
 
                                                                v->cur_order_index++;
713
 
                                                                InvalidateVehicleOrder(v);
 
592
        if (v->u.ship.state != TRACK_BIT_WORMHOLE) {
 
593
                /* Not on a bridge */
 
594
                if (gp.old_tile == gp.new_tile) {
 
595
                        /* Staying in tile */
 
596
                        if (v->IsInDepot()) {
 
597
                                gp.x = v->x_pos;
 
598
                                gp.y = v->y_pos;
 
599
                        } else {
 
600
                                /* Not inside depot */
 
601
                                r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
 
602
                                if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
 
603
 
 
604
                                /* A leave station order only needs one tick to get processed, so we can
 
605
                                 * always skip ahead. */
 
606
                                if (v->current_order.IsType(OT_LEAVESTATION)) {
 
607
                                        v->current_order.Free();
 
608
                                        InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 
609
                                } else if (v->dest_tile != 0) {
 
610
                                        /* We have a target, let's see if we reached it... */
 
611
                                        if (v->current_order.IsType(OT_GOTO_STATION) &&
 
612
                                                        GetStation(v->current_order.GetDestination())->IsBuoy() &&
 
613
                                                        DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
 
614
                                                /* We got within 3 tiles of our target buoy, so let's skip to our
 
615
                                                 * next order */
 
616
                                                UpdateVehicleTimetable(v, true);
 
617
                                                v->cur_order_index++;
 
618
                                                v->current_order.MakeDummy();
 
619
                                                InvalidateVehicleOrder(v, 0);
 
620
                                        } else {
 
621
                                                /* Non-buoy orders really need to reach the tile */
 
622
                                                if (v->dest_tile == gp.new_tile) {
 
623
                                                        if (v->current_order.IsType(OT_GOTO_DEPOT)) {
 
624
                                                                if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) {
 
625
                                                                        VehicleEnterDepot(v);
 
626
                                                                        return;
 
627
                                                                }
 
628
                                                        } else if (v->current_order.IsType(OT_GOTO_STATION)) {
 
629
                                                                v->last_station_visited = v->current_order.GetDestination();
 
630
 
 
631
                                                                /* Process station in the orderlist. */
 
632
                                                                Station *st = GetStation(v->current_order.GetDestination());
 
633
                                                                if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
 
634
                                                                        ShipArrivesAt(v, st);
 
635
                                                                        v->BeginLoading();
 
636
                                                                } else { // leave stations without docks right aways
 
637
                                                                        v->current_order.MakeLeaveStation();
 
638
                                                                        v->cur_order_index++;
 
639
                                                                        InvalidateVehicleOrder(v, 0);
 
640
                                                                }
714
641
                                                        }
715
642
                                                }
716
643
                                        }
717
644
                                }
718
645
                        }
 
646
                } else {
 
647
                        DiagDirection diagdir;
 
648
                        /* New tile */
 
649
                        if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY()) {
 
650
                                goto reverse_direction;
 
651
                        }
 
652
 
 
653
                        dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile);
 
654
                        assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW);
 
655
                        diagdir = DirToDiagDir(dir);
 
656
                        tracks = GetAvailShipTracks(gp.new_tile, diagdir);
 
657
                        if (tracks == TRACK_BIT_NONE) goto reverse_direction;
 
658
 
 
659
                        /* Choose a direction, and continue if we find one */
 
660
                        track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks);
 
661
                        if (track == INVALID_TRACK) goto reverse_direction;
 
662
 
 
663
                        b = _ship_subcoord[diagdir][track];
 
664
 
 
665
                        gp.x = (gp.x & ~0xF) | b[0];
 
666
                        gp.y = (gp.y & ~0xF) | b[1];
 
667
 
 
668
                        /* Call the landscape function and tell it that the vehicle entered the tile */
 
669
                        r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
 
670
                        if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
 
671
 
 
672
                        if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
 
673
                                v->tile = gp.new_tile;
 
674
                                v->u.ship.state = TrackToTrackBits(track);
 
675
                        }
 
676
 
 
677
                        v->direction = (Direction)b[2];
719
678
                }
720
679
        } else {
721
 
                DiagDirection diagdir;
722
 
                /* New tile */
723
 
                if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY()) {
724
 
                        goto reverse_direction;
725
 
                }
726
 
 
727
 
                dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile);
728
 
                assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW);
729
 
                diagdir = DirToDiagDir(dir);
730
 
                tracks = GetAvailShipTracks(gp.new_tile, diagdir);
731
 
                if (tracks == TRACK_BIT_NONE) goto reverse_direction;
732
 
 
733
 
                /* Choose a direction, and continue if we find one */
734
 
                track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks);
735
 
                if (track == INVALID_TRACK) goto reverse_direction;
736
 
 
737
 
                b = _ship_subcoord[diagdir][track];
738
 
 
739
 
                gp.x = (gp.x & ~0xF) | b[0];
740
 
                gp.y = (gp.y & ~0xF) | b[1];
741
 
 
742
 
                /* Call the landscape function and tell it that the vehicle entered the tile */
743
 
                r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
744
 
                if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
745
 
 
746
 
                if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
747
 
                        v->tile = gp.new_tile;
748
 
                        v->u.ship.state = TrackToTrackBits(track);
749
 
                }
750
 
 
751
 
                v->direction = (Direction)b[2];
 
680
                /* On a bridge */
 
681
                if (!IsTileType(gp.new_tile, MP_TUNNELBRIDGE) || !HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
 
682
                        v->x_pos = gp.x;
 
683
                        v->y_pos = gp.y;
 
684
                        VehicleMove(v, !(v->vehstatus & VS_HIDDEN));
 
685
                        return;
 
686
                }
752
687
        }
753
688
 
754
689
        /* update image of ship, as well as delta XY */
760
695
getout:
761
696
        v->UpdateDeltaXY(dir);
762
697
        v->cur_image = v->GetImage(dir);
763
 
        VehiclePositionChanged(v);
764
 
        EndVehicleMove(v);
 
698
        VehicleMove(v, true);
765
699
        return;
766
700
 
767
701
reverse_direction:
784
718
        ShipController(this);
785
719
}
786
720
 
787
 
 
788
 
void ShipsYearlyLoop()
789
 
{
790
 
        Vehicle *v;
791
 
 
792
 
        FOR_ALL_VEHICLES(v) {
793
 
                if (v->type == VEH_SHIP) {
794
 
                        v->profit_last_year = v->profit_this_year;
795
 
                        v->profit_this_year = 0;
796
 
                        InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
797
 
                }
798
 
        }
799
 
}
800
 
 
801
721
/** Build a ship.
802
722
 * @param tile tile of depot where ship is built
803
723
 * @param flags type of operation
804
724
 * @param p1 ship type being built (engine)
805
725
 * @param p2 unused
806
726
 */
807
 
CommandCost CmdBuildShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
727
CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
808
728
{
809
 
        CommandCost value;
810
729
        UnitID unit_num;
811
 
        Engine *e;
812
 
 
813
 
        if (!IsEngineBuildable(p1, VEH_SHIP, _current_player)) return_cmd_error(STR_SHIP_NOT_AVAILABLE);
814
 
 
815
 
        value = EstimateShipCost(p1);
 
730
 
 
731
        if (!IsEngineBuildable(p1, VEH_SHIP, _current_company)) return_cmd_error(STR_SHIP_NOT_AVAILABLE);
 
732
 
 
733
        const Engine *e = GetEngine(p1);
 
734
        CommandCost value(EXPENSES_NEW_VEHICLES, e->GetCost());
 
735
 
 
736
        /* Engines without valid cargo should not be available */
 
737
        if (e->GetDefaultCargoType() == CT_INVALID) return CMD_ERROR;
 
738
 
816
739
        if (flags & DC_QUERY_COST) return value;
817
740
 
818
741
        /* The ai_new queries the vehicle cost before building the route,
819
742
         * so we must check against cheaters no sooner than now. --pasky */
820
 
        if (!IsTileDepotType(tile, TRANSPORT_WATER)) return CMD_ERROR;
821
 
        if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
 
743
        if (!IsShipDepotTile(tile)) return CMD_ERROR;
 
744
        if (!IsTileOwner(tile, _current_company)) return CMD_ERROR;
822
745
 
823
746
        unit_num = (flags & DC_AUTOREPLACE) ? 0 : GetFreeUnitNumber(VEH_SHIP);
824
747
 
825
 
        if (!Vehicle::AllocateList(NULL, 1) || unit_num > _patches.max_ships)
 
748
        if (!Vehicle::CanAllocateItem() || unit_num > _settings_game.vehicle.max_ships)
826
749
                return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
827
750
 
828
751
        if (flags & DC_EXEC) {
834
757
                Vehicle *v = new Ship();
835
758
                v->unitnumber = unit_num;
836
759
 
837
 
                v->owner = _current_player;
 
760
                v->owner = _current_company;
838
761
                v->tile = tile;
839
762
                x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
840
763
                y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
848
771
                v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
849
772
 
850
773
                v->spritenum = svi->image_index;
851
 
                v->cargo_type = svi->cargo_type;
 
774
                v->cargo_type = e->GetDefaultCargoType();
852
775
                v->cargo_subtype = 0;
853
776
                v->cargo_cap = svi->capacity;
854
777
                v->value = value.GetCost();
857
780
                v->max_speed = svi->max_speed;
858
781
                v->engine_type = p1;
859
782
 
860
 
                e = GetEngine(p1);
861
783
                v->reliability = e->reliability;
862
784
                v->reliability_spd_dec = e->reliability_spd_dec;
863
 
                v->max_age = e->lifelength * 366;
 
785
                v->max_age = e->lifelength * DAYS_IN_LEAP_YEAR;
864
786
                _new_vehicle_id = v->index;
865
787
 
866
788
                v->name = NULL;
867
789
                v->u.ship.state = TRACK_BIT_DEPOT;
868
790
 
869
 
                v->service_interval = _patches.servint_ships;
 
791
                v->service_interval = _settings_game.vehicle.servint_ships;
870
792
                v->date_of_last_service = _date;
871
793
                v->build_year = _cur_year;
872
794
                v->cur_image = 0x0E5E;
877
799
 
878
800
                v->cargo_cap = GetVehicleProperty(v, 0x0D, svi->capacity);
879
801
 
880
 
                VehiclePositionChanged(v);
 
802
                VehicleMove(v, false);
881
803
 
882
804
                InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
883
 
                RebuildVehicleLists();
 
805
                InvalidateWindowClassesData(WC_SHIPS_LIST, 0);
884
806
                InvalidateWindow(WC_COMPANY, v->owner);
885
 
                if (IsLocalPlayer())
 
807
                if (IsLocalCompany())
886
808
                        InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Ship window
887
809
 
888
 
                GetPlayer(_current_player)->num_engines[p1]++;
 
810
                GetCompany(_current_company)->num_engines[p1]++;
889
811
        }
890
812
 
891
813
        return value;
897
819
 * @param p1 vehicle ID to be sold
898
820
 * @param p2 unused
899
821
 */
900
 
CommandCost CmdSellShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
822
CommandCost CmdSellShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
901
823
{
902
824
        Vehicle *v;
903
825
 
916
838
        CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
917
839
 
918
840
        if (flags & DC_EXEC) {
919
 
                InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
920
 
                RebuildVehicleLists();
921
 
                InvalidateWindow(WC_COMPANY, v->owner);
922
 
                DeleteWindowById(WC_VEHICLE_VIEW, v->index);
923
 
                DeleteDepotHighlightOfVehicle(v);
924
841
                delete v;
925
842
        }
926
843
 
927
844
        return ret;
928
845
}
929
846
 
930
 
/** Start/Stop a ship.
931
 
 * @param tile unused
932
 
 * @param flags type of operation
933
 
 * @param p1 ship ID to start/stop
934
 
 * @param p2 unused
935
 
 */
936
 
CommandCost CmdStartStopShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
847
bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
937
848
{
938
 
        if (!IsValidVehicleID(p1)) return CMD_ERROR;
939
 
 
940
 
        Vehicle *v = GetVehicle(p1);
941
 
 
942
 
        if (v->type != VEH_SHIP || !CheckOwnership(v->owner)) return CMD_ERROR;
943
 
 
944
 
        /* Check if this ship can be started/stopped. The callback will fail or
945
 
         * return 0xFF if it can. */
946
 
        uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
947
 
        if (callback != CALLBACK_FAILED && GB(callback, 0, 8) != 0xFF) {
948
 
                StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
949
 
                return_cmd_error(error);
950
 
        }
951
 
 
952
 
        if (flags & DC_EXEC) {
953
 
                if (v->IsStoppedInDepot()) {
954
 
                        DeleteVehicleNews(p1, STR_981C_SHIP_IS_WAITING_IN_DEPOT);
955
 
                }
956
 
 
957
 
                v->vehstatus ^= VS_STOPPED;
958
 
                v->cur_speed = 0;
959
 
                InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
960
 
                InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
961
 
                InvalidateWindowClasses(WC_SHIPS_LIST);
962
 
        }
963
 
 
964
 
        return CommandCost();
 
849
        const Depot *depot = FindClosestShipDepot(this);
 
850
 
 
851
        if (depot == NULL) return false;
 
852
 
 
853
        if (location    != NULL) *location    = depot->xy;
 
854
        if (destination != NULL) *destination = depot->index;
 
855
 
 
856
        return true;
965
857
}
966
858
 
967
859
/** Send a ship to the depot.
972
864
 * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
973
865
 * - p2 bit 8-10 - VLW flag (for mass goto depot)
974
866
 */
975
 
CommandCost CmdSendShipToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
867
CommandCost CmdSendShipToDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
976
868
{
977
 
        Vehicle *v;
978
 
        const Depot *dep;
979
 
 
980
869
        if (p2 & DEPOT_MASS_SEND) {
981
870
                /* Mass goto depot requested */
982
871
                if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
983
 
                return SendAllVehiclesToDepot(VEH_SHIP, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
 
872
                return SendAllVehiclesToDepot(VEH_SHIP, flags, p2 & DEPOT_SERVICE, _current_company, (p2 & VLW_MASK), p1);
984
873
        }
985
874
 
986
875
        if (!IsValidVehicleID(p1)) return CMD_ERROR;
987
876
 
988
 
        v = GetVehicle(p1);
989
 
 
990
 
        if (v->type != VEH_SHIP || !CheckOwnership(v->owner)) return CMD_ERROR;
991
 
 
992
 
        if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
993
 
 
994
 
        if (v->IsInDepot()) return CMD_ERROR;
995
 
 
996
 
        /* If the current orders are already goto-depot */
997
 
        if (v->current_order.type == OT_GOTO_DEPOT) {
998
 
                if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
999
 
                        /* We called with a different DEPOT_SERVICE setting.
1000
 
                         * Now we change the setting to apply the new one and let the vehicle head for the same depot.
1001
 
                         * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
1002
 
                        if (flags & DC_EXEC) {
1003
 
                                ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
1004
 
                                ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
1005
 
                                InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
1006
 
                        }
1007
 
                        return CommandCost();
1008
 
                }
1009
 
 
1010
 
                if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
1011
 
                if (flags & DC_EXEC) {
1012
 
                        /* If the orders to 'goto depot' are in the orders list (forced servicing),
1013
 
                         * then skip to the next order; effectively cancelling this forced service */
1014
 
                        if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS))
1015
 
                                v->cur_order_index++;
1016
 
 
1017
 
                        v->current_order.type = OT_DUMMY;
1018
 
                        v->current_order.flags = 0;
1019
 
                        InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
1020
 
                }
1021
 
                return CommandCost();
1022
 
        }
1023
 
 
1024
 
        dep = FindClosestShipDepot(v);
1025
 
        if (dep == NULL) return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT);
1026
 
 
1027
 
        if (flags & DC_EXEC) {
1028
 
                if (v->current_order.type == OT_LOADING) v->LeaveStation();
1029
 
 
1030
 
                v->dest_tile = dep->xy;
1031
 
                v->current_order.type = OT_GOTO_DEPOT;
1032
 
                v->current_order.flags = OFB_NON_STOP;
1033
 
                if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
1034
 
                v->current_order.refit_cargo = CT_INVALID;
1035
 
                v->current_order.dest = dep->index;
1036
 
                InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
1037
 
        }
1038
 
 
1039
 
        return CommandCost();
 
877
        Vehicle *v = GetVehicle(p1);
 
878
 
 
879
        if (v->type != VEH_SHIP) return CMD_ERROR;
 
880
 
 
881
        return v->SendToDepot(flags, (DepotCommand)(p2 & DEPOT_COMMAND_MASK));
1040
882
}
1041
883
 
1042
884
 
1050
892
 * - p2 = (bit 16) - refit only this vehicle (ignored)
1051
893
 * @return cost of refit or error
1052
894
 */
1053
 
CommandCost CmdRefitShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
895
CommandCost CmdRefitShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1054
896
{
1055
897
        Vehicle *v;
1056
898
        CommandCost cost(EXPENSES_SHIP_RUN);
1057
 
        CargoID new_cid = GB(p2, 0, 8); //gets the cargo number
 
899
        CargoID new_cid = GB(p2, 0, 8); // gets the cargo number
1058
900
        byte new_subtype = GB(p2, 8, 8);
1059
901
        uint16 capacity = CALLBACK_FAILED;
1060
902
 
1090
932
        }
1091
933
        _returned_refit_capacity = capacity;
1092
934
 
1093
 
        if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
 
935
        if (new_cid != v->cargo_type) {
1094
936
                cost = GetRefitCost(v->engine_type);
1095
937
        }
1096
938
 
1099
941
                v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
1100
942
                v->cargo_type = new_cid;
1101
943
                v->cargo_subtype = new_subtype;
 
944
                v->colourmap = PAL_NONE; // invalidate vehicle colour map
1102
945
                InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
1103
946
                InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
1104
 
                RebuildVehicleLists();
 
947
                InvalidateWindowClassesData(WC_SHIPS_LIST, 0);
1105
948
        }
1106
949
 
1107
950
        return cost;