OpenTTD Source 20251019-master-g9f7f314f81
ship_cmd.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "ship.h"
12#include "landscape.h"
13#include "timetable.h"
14#include "news_func.h"
15#include "company_func.h"
16#include "depot_base.h"
17#include "station_base.h"
18#include "newgrf_engine.h"
21#include "newgrf_sound.h"
22#include "strings_func.h"
23#include "window_func.h"
26#include "vehicle_func.h"
27#include "sound_func.h"
28#include "ai/ai.hpp"
29#include "game/game.hpp"
30#include "engine_base.h"
31#include "company_base.h"
32#include "tunnelbridge_map.h"
33#include "zoom_func.h"
34#include "framerate_type.h"
35#include "industry.h"
36#include "industry_map.h"
37#include "ship_cmd.h"
38
39#include "table/strings.h"
40
41#include <unordered_set>
42
43#include "safeguards.h"
44
47
54{
55 if (HasTileWaterClass(tile)) return GetWaterClass(tile);
56 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
58 return WATER_CLASS_CANAL;
59 }
60 if (IsTileType(tile, MP_RAILWAY)) {
61 assert(GetRailGroundType(tile) == RAIL_GROUND_WATER);
62 return WATER_CLASS_SEA;
63 }
64 NOT_REACHED();
65}
66
67static const uint16_t _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
68
69template <>
70bool IsValidImageIndex<VEH_SHIP>(uint8_t image_index)
71{
72 return image_index < lengthof(_ship_sprites);
73}
74
75static inline TrackBits GetTileShipTrackStatus(TileIndex tile)
76{
78}
79
80static void GetShipIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result)
81{
82 const Engine *e = Engine::Get(engine);
83 uint8_t spritenum = e->VehInfo<ShipVehicleInfo>().image_index;
84
85 if (IsCustomVehicleSpriteNum(spritenum)) {
86 GetCustomVehicleIcon(engine, DIR_W, image_type, result);
87 if (result->IsValid()) return;
88
89 spritenum = e->original_image_index;
90 }
91
92 assert(IsValidImageIndex<VEH_SHIP>(spritenum));
93 result->Set(DIR_W + _ship_sprites[spritenum]);
94}
95
96void DrawShipEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
97{
99 GetShipIcon(engine, image_type, &seq);
100
101 Rect rect;
102 seq.GetBounds(&rect);
103 preferred_x = Clamp(preferred_x,
104 left - UnScaleGUI(rect.left),
105 right - UnScaleGUI(rect.right));
106
107 seq.Draw(preferred_x, y, pal, pal == PALETTE_CRASH);
108}
109
119void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
120{
122 GetShipIcon(engine, image_type, &seq);
123
124 Rect rect;
125 seq.GetBounds(&rect);
126
127 width = UnScaleGUI(rect.Width());
128 height = UnScaleGUI(rect.Height());
129 xoffs = UnScaleGUI(rect.left);
130 yoffs = UnScaleGUI(rect.top);
131}
132
133void Ship::GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
134{
135 uint8_t spritenum = this->spritenum;
136
137 if (image_type == EIT_ON_MAP) direction = this->rotation;
138
139 if (IsCustomVehicleSpriteNum(spritenum)) {
140 GetCustomVehicleSprite(this, direction, image_type, result);
141 if (result->IsValid()) return;
142
144 }
145
146 assert(IsValidImageIndex<VEH_SHIP>(spritenum));
147 result->Set(_ship_sprites[spritenum] + direction);
148}
149
150static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)
151{
152 const int max_region_distance = (max_distance / WATER_REGION_EDGE_LENGTH) + 1;
153
154 static std::unordered_set<int> visited_patch_hashes;
155 static std::deque<WaterRegionPatchDesc> patches_to_search;
156 visited_patch_hashes.clear();
157 patches_to_search.clear();
158
159 /* Step 1: find a set of reachable Water Region Patches using BFS. */
160 const WaterRegionPatchDesc start_patch = GetWaterRegionPatchInfo(v->tile);
161 patches_to_search.push_back(start_patch);
162 visited_patch_hashes.insert(CalculateWaterRegionPatchHash(start_patch));
163
164 while (!patches_to_search.empty()) {
165 /* Remove first patch from the queue and make it the current patch. */
166 const WaterRegionPatchDesc current_node = patches_to_search.front();
167 patches_to_search.pop_front();
168
169 /* Add neighbours of the current patch to the search queue. */
170 VisitWaterRegionPatchCallback visit_func = [&](const WaterRegionPatchDesc &water_region_patch) {
171 /* Note that we check the max distance per axis, not the total distance. */
172 if (std::abs(water_region_patch.x - start_patch.x) > max_region_distance ||
173 std::abs(water_region_patch.y - start_patch.y) > max_region_distance) return;
174
175 const int hash = CalculateWaterRegionPatchHash(water_region_patch);
176 if (visited_patch_hashes.count(hash) == 0) {
177 visited_patch_hashes.insert(hash);
178 patches_to_search.push_back(water_region_patch);
179 }
180 };
181
182 VisitWaterRegionPatchNeighbours(current_node, visit_func);
183 }
184
185 /* Step 2: Find the closest depot within the reachable Water Region Patches. */
186 const Depot *best_depot = nullptr;
187 uint best_dist_sq = std::numeric_limits<uint>::max();
188 for (const Depot *depot : Depot::Iterate()) {
189 const TileIndex tile = depot->xy;
190 if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) {
191 const uint dist_sq = DistanceSquare(tile, v->tile);
192 if (dist_sq < best_dist_sq && dist_sq <= max_distance * max_distance &&
193 visited_patch_hashes.count(CalculateWaterRegionPatchHash(GetWaterRegionPatchInfo(tile))) > 0) {
194 best_dist_sq = dist_sq;
195 best_depot = depot;
196 }
197 }
198 }
199
200 return best_depot;
201}
202
203static void CheckIfShipNeedsService(Vehicle *v)
204{
205 if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
206 if (v->IsChainInDepot()) {
208 return;
209 }
210
212
213 const Depot *depot = FindClosestShipDepot(v, max_distance);
214
215 if (depot == nullptr) {
216 if (v->current_order.IsType(OT_GOTO_DEPOT)) {
219 }
220 return;
221 }
222
224 v->SetDestTile(depot->xy);
226}
227
232{
233 const ShipVehicleInfo *svi = ShipVehInfo(this->engine_type);
234
235 /* Get speed fraction for the current water type. Aqueducts are always canals. */
236 bool is_ocean = GetEffectiveWaterClass(this->tile) == WATER_CLASS_SEA;
237 uint raw_speed = GetVehicleProperty(this, PROP_SHIP_SPEED, svi->max_speed);
238 this->vcache.cached_max_speed = svi->ApplyWaterClassSpeedFrac(raw_speed, is_ocean);
239
240 /* Update cargo aging period. */
241 this->vcache.cached_cargo_age_period = GetVehicleProperty(this, PROP_SHIP_CARGO_AGE_PERIOD, EngInfo(this->engine_type)->cargo_age_period);
242
243 this->UpdateVisualEffect();
244}
245
247{
248 const Engine *e = this->GetEngine();
249 uint cost_factor = GetVehicleProperty(this, PROP_SHIP_RUNNING_COST_FACTOR, e->VehInfo<ShipVehicleInfo>().running_cost);
250 return GetPrice(PR_RUNNING_SHIP, cost_factor, e->GetGRF());
251}
252
255{
256 AgeVehicle(this);
257}
258
261{
262 EconomyAgeVehicle(this);
263
264 if ((++this->day_counter & 7) == 0) {
266 }
267
268 CheckVehicleBreakdown(this);
269 CheckIfShipNeedsService(this);
270
271 CheckOrders(this);
272
273 if (this->running_ticks == 0) return;
274
276
277 this->profit_this_year -= cost.GetCost();
278 this->running_ticks = 0;
279
281
283 /* we need this for the profit */
285}
286
288{
290
291 if (this->IsInDepot()) {
292 /* We'll assume the ship is facing outwards */
294 }
295
296 if (this->state == TRACK_BIT_WORMHOLE) {
297 /* ship on aqueduct, so just use its direction and assume a diagonal track */
299 }
300
302}
303
305{
306 this->colourmap = PAL_NONE;
307 this->UpdateViewport(true, false);
308 this->UpdateCache();
309}
310
311void Ship::PlayLeaveStationSound(bool force) const
312{
313 if (PlayVehicleSound(this, VSE_START, force)) return;
314 SndPlayVehicleFx(ShipVehInfo(this->engine_type)->sfx, this);
315}
316
318{
319 if (station == this->last_station_visited) this->last_station_visited = StationID::Invalid();
320
321 const Station *st = Station::Get(station);
322 if (CanVehicleUseStation(this, st)) {
323 return st->xy;
324 } else {
326 return TileIndex{};
327 }
328}
329
331{
332 static constexpr SpriteBounds ship_bounds[DIR_END] = {
333 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // N
334 {{-16, -3, 0}, {32, 6, 6}, {}}, // NE
335 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // E
336 {{ -3, -16, 0}, { 6, 32, 6}, {}}, // SE
337 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // S
338 {{-16, -3, 0}, {32, 6, 6}, {}}, // SW
339 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // W
340 {{ -3, -16, 0}, { 6, 32, 6}, {}}, // NW
341 };
342
343 this->bounds = ship_bounds[this->rotation];
344
345 if (this->direction != this->rotation) {
346 /* If we are rotating, then it is possible the ship was moved to its next position. In that
347 * case, because we are still showing the old direction, the ship will appear to glitch sideways
348 * slightly. We can work around this by applying an additional offset to make the ship appear
349 * where it was before it moved. */
350 this->bounds.origin.x -= this->x_pos - this->rotation_x_pos;
351 this->bounds.origin.y -= this->y_pos - this->rotation_y_pos;
352 }
353}
354
355static bool CheckReverseShip(const Ship *v, Trackdir *trackdir = nullptr)
356{
357 /* Ask pathfinder for best direction */
358 return YapfShipCheckReverse(v, trackdir);
359}
360
367{
368 if (!v->IsChainInDepot()) return false;
369
370 /* Check if we should wait here for unbunching. */
371 if (v->IsWaitingForUnbunching()) return true;
372
373 /* We are leaving a depot, but have to go to the exact same one; re-enter */
374 if (v->current_order.IsType(OT_GOTO_DEPOT) &&
377 return true;
378 }
379
380 /* Don't leave depot if no destination set */
381 if (v->dest_tile == 0) return true;
382
383 /* Don't leave depot if another vehicle is already entering/leaving */
384 /* This helps avoid CPU load if many ships are set to start at the same time */
385 if (HasVehicleOnTile(v->tile, [](const Vehicle *u) {
386 return u->type == VEH_SHIP && u->cur_speed != 0;
387 })) return true;
388
391 if (CheckReverseShip(v)) v->direction = ReverseDir(v->direction);
392
394 v->rotation = v->direction;
396 v->cur_speed = 0;
397 v->UpdateViewport(true, true);
399
405
406 return false;
407}
408
414static uint ShipAccelerate(Vehicle *v)
415{
416 uint speed;
417 speed = std::min<uint>(v->cur_speed + v->acceleration, v->vcache.cached_max_speed);
418 speed = std::min<uint>(speed, v->current_order.GetMaxSpeed() * 2);
419
420 /* updates statusbar only if speed have changed to save CPU time */
421 if (speed != v->cur_speed) {
422 v->cur_speed = speed;
424 }
425
426 const uint advance_speed = v->GetAdvanceSpeed(speed);
427 const uint number_of_steps = (advance_speed + v->progress) / v->GetAdvanceDistance();
428 const uint remainder = (advance_speed + v->progress) % v->GetAdvanceDistance();
429 assert(remainder <= std::numeric_limits<uint8_t>::max());
430 v->progress = static_cast<uint8_t>(remainder);
431 return number_of_steps;
432}
433
439static void ShipArrivesAt(const Vehicle *v, Station *st)
440{
441 /* Check if station was ever visited before */
442 if (!(st->had_vehicle_of_type & HVOT_SHIP)) {
443 st->had_vehicle_of_type |= HVOT_SHIP;
444
446 GetEncodedString(STR_NEWS_FIRST_SHIP_ARRIVAL, st->index),
448 v->index,
449 st->index
450 );
451 AI::NewEvent(v->owner, new ScriptEventStationFirstVehicle(st->index, v->index));
452 Game::NewEvent(new ScriptEventStationFirstVehicle(st->index, v->index));
453 }
454}
455
456
466{
467 bool path_found = true;
468 Track track;
469
470 if (v->dest_tile == 0) {
471 /* No destination, don't invoke pathfinder. */
472 track = TrackBitsToTrack(v->state);
473 if (!IsDiagonalTrack(track)) track = TrackToOppositeTrack(track);
474 if (!HasBit(tracks, track)) track = FindFirstTrack(tracks);
475 path_found = false;
476 } else {
477 /* Attempt to follow cached path. */
478 if (!v->path.empty()) {
479 track = TrackdirToTrack(v->path.back().trackdir);
480
481 if (HasBit(tracks, track)) {
482 v->path.pop_back();
483 /* HandlePathfindResult() is not called here because this is not a new pathfinder result. */
484 return track;
485 }
486
487 /* Cached path is invalid so continue with pathfinder. */
488 v->path.clear();
489 }
490
491 track = YapfShipChooseTrack(v, tile, path_found, v->path);
492 }
493
494 v->HandlePathfindingResult(path_found);
495 return track;
496}
497
505{
506 TrackBits tracks = GetTileShipTrackStatus(tile) & DiagdirReachesTracks(dir);
507
508 return tracks;
509}
510
523 /* DIAGDIR_NE */
524 {
525 {15, 8, DIR_NE}, // TRACK_X
526 { 0, 0, INVALID_DIR}, // TRACK_Y
527 { 0, 0, INVALID_DIR}, // TRACK_UPPER
528 {15, 8, DIR_E}, // TRACK_LOWER
529 {15, 7, DIR_N}, // TRACK_LEFT
530 { 0, 0, INVALID_DIR}, // TRACK_RIGHT
531 },
532 /* DIAGDIR_SE */
533 {
534 { 0, 0, INVALID_DIR}, // TRACK_X
535 { 8, 0, DIR_SE}, // TRACK_Y
536 { 7, 0, DIR_E}, // TRACK_UPPER
537 { 0, 0, INVALID_DIR}, // TRACK_LOWER
538 { 8, 0, DIR_S}, // TRACK_LEFT
539 { 0, 0, INVALID_DIR}, // TRACK_RIGHT
540 },
541 /* DIAGDIR_SW */
542 {
543 { 0, 8, DIR_SW}, // TRACK_X
544 { 0, 0, INVALID_DIR}, // TRACK_Y
545 { 0, 7, DIR_W}, // TRACK_UPPER
546 { 0, 0, INVALID_DIR}, // TRACK_LOWER
547 { 0, 0, INVALID_DIR}, // TRACK_LEFT
548 { 0, 8, DIR_S}, // TRACK_RIGHT
549 },
550 /* DIAGDIR_NW */
551 {
552 { 0, 0, INVALID_DIR}, // TRACK_X
553 { 8, 15, DIR_NW}, // TRACK_Y
554 { 0, 0, INVALID_DIR}, // TRACK_UPPER
555 { 8, 15, DIR_W}, // TRACK_LOWER
556 { 0, 0, INVALID_DIR}, // TRACK_LEFT
557 { 7, 15, DIR_N}, // TRACK_RIGHT
558 }
559};
560
566static int ShipTestUpDownOnLock(const Ship *v)
567{
568 /* Suitable tile? */
569 if (!IsTileType(v->tile, MP_WATER) || !IsLock(v->tile) || GetLockPart(v->tile) != LOCK_PART_MIDDLE) return 0;
570
571 /* Must be at the centre of the lock */
572 if ((v->x_pos & 0xF) != 8 || (v->y_pos & 0xF) != 8) return 0;
573
575 assert(IsValidDiagDirection(diagdir));
576
577 if (DirToDiagDir(v->direction) == diagdir) {
578 /* Move up */
579 return (v->z_pos < GetTileMaxZ(v->tile) * (int)TILE_HEIGHT) ? 1 : 0;
580 } else {
581 /* Move down */
582 return (v->z_pos > GetTileZ(v->tile) * (int)TILE_HEIGHT) ? -1 : 0;
583 }
584}
585
592{
593 /* Moving up/down through lock */
594 int dz = ShipTestUpDownOnLock(v);
595 if (dz == 0) return false;
596
597 if (v->cur_speed != 0) {
598 v->cur_speed = 0;
600 }
601
602 if ((v->tick_counter & 7) == 0) {
603 v->z_pos += dz;
604 v->UpdatePosition();
605 v->UpdateViewport(true, true);
606 }
607
608 return true;
609}
610
618{
619 assert(IsDockingTile(tile));
620 /* Check each tile adjacent to docking tile. */
621 for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) {
622 TileIndex t = tile + TileOffsByDiagDir(d);
623 if (!IsValidTile(t)) continue;
624 if (IsDockTile(t) && GetStationIndex(t) == station && IsDockWaterPart(t)) return true;
625 if (IsTileType(t, MP_INDUSTRY)) {
626 const Industry *i = Industry::GetByTile(t);
627 if (i->neutral_station != nullptr && i->neutral_station->index == station) return true;
628 }
629 if (IsTileType(t, MP_STATION) && IsOilRig(t) && GetStationIndex(t) == station) return true;
630 }
631 return false;
632}
633
634static void ReverseShipIntoTrackdir(Ship *v, Trackdir trackdir)
635{
636 static constexpr Direction _trackdir_to_direction[] = {
639 };
640
641 v->direction = _trackdir_to_direction[trackdir];
642 assert(v->direction != INVALID_DIR);
644
645 /* Remember our current location to avoid movement glitch */
646 v->rotation_x_pos = v->x_pos;
647 v->rotation_y_pos = v->y_pos;
648 v->cur_speed = 0;
649 v->path.clear();
650
651 v->UpdatePosition();
652 v->UpdateViewport(true, true);
653}
654
655static void ReverseShip(Ship *v)
656{
658
659 /* Remember our current location to avoid movement glitch */
660 v->rotation_x_pos = v->x_pos;
661 v->rotation_y_pos = v->y_pos;
662 v->cur_speed = 0;
663 v->path.clear();
664
665 v->UpdatePosition();
666 v->UpdateViewport(true, true);
667}
668
669static void ShipController(Ship *v)
670{
671 v->tick_counter++;
673
674 if (v->HandleBreakdown()) return;
675
676 if (v->vehstatus.Test(VehState::Stopped)) return;
677
678 if (ProcessOrders(v) && CheckReverseShip(v)) return ReverseShip(v);
679
680 v->HandleLoading();
681
682 if (v->current_order.IsType(OT_LOADING)) return;
683
684 if (CheckShipStayInDepot(v)) return;
685
686 v->ShowVisualEffect();
687
688 /* Rotating on spot */
689 if (v->direction != v->rotation) {
690 if ((v->tick_counter & 7) == 0) {
693 /* Invalidate the sprite cache direction to force recalculation of viewport */
695 v->UpdateViewport(true, true);
696 }
697 return;
698 }
699
700 if (ShipMoveUpDownOnLock(v)) return;
701
702 const uint number_of_steps = ShipAccelerate(v);
703 for (uint i = 0; i < number_of_steps; ++i) {
704 if (ShipMoveUpDownOnLock(v)) return;
705
707 if (v->state != TRACK_BIT_WORMHOLE) {
708 /* Not on a bridge */
709 if (gp.old_tile == gp.new_tile) {
710 /* Staying in tile */
711 if (v->IsInDepot()) {
712 gp.x = v->x_pos;
713 gp.y = v->y_pos;
714 } else {
715 /* Not inside depot */
716 auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
717 if (vets.Test(VehicleEnterTileState::CannotEnter)) return ReverseShip(v);
718
719 /* A leave station order only needs one tick to get processed, so we can
720 * always skip ahead. */
721 if (v->current_order.IsType(OT_LEAVESTATION)) {
722 v->current_order.Free();
724 /* Test if continuing forward would lead to a dead-end, moving into the dock. */
725 const DiagDirection exitdir = VehicleExitDir(v->direction, v->state);
726 const TileIndex tile = TileAddByDiagDir(v->tile, exitdir);
727 if (TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0, exitdir)) == TRACK_BIT_NONE) return ReverseShip(v);
728 } else if (v->dest_tile != 0) {
729 /* We have a target, let's see if we reached it... */
730 if (v->current_order.IsType(OT_GOTO_WAYPOINT) &&
731 DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
732 /* We got within 3 tiles of our target buoy, so let's skip to our
733 * next order */
734 UpdateVehicleTimetable(v, true);
737 } else if (v->current_order.IsType(OT_GOTO_DEPOT) &&
738 v->dest_tile == gp.new_tile) {
739 /* Depot orders really need to reach the tile */
740 if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) {
742 return;
743 }
744 } else if (v->current_order.IsType(OT_GOTO_STATION) && IsDockingTile(gp.new_tile)) {
745 /* Process station in the orderlist. */
746 Station *st = Station::Get(v->current_order.GetDestination().ToStationID());
749 if (st->facilities.Test(StationFacility::Dock)) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
750 ShipArrivesAt(v, st);
751 v->BeginLoading();
752 } else { // leave stations without docks right away
755 }
756 }
757 }
758 }
759 }
760 } else {
761 /* New tile */
762 if (!IsValidTile(gp.new_tile)) return ReverseShip(v);
763
764 const DiagDirection diagdir = DiagdirBetweenTiles(gp.old_tile, gp.new_tile);
765 assert(diagdir != INVALID_DIAGDIR);
766 const TrackBits tracks = GetAvailShipTracks(gp.new_tile, diagdir);
767 if (tracks == TRACK_BIT_NONE) {
768 Trackdir trackdir = INVALID_TRACKDIR;
769 CheckReverseShip(v, &trackdir);
770 if (trackdir == INVALID_TRACKDIR) return ReverseShip(v);
771 return ReverseShipIntoTrackdir(v, trackdir);
772 }
773
774 /* Choose a direction, and continue if we find one */
775 const Track track = ChooseShipTrack(v, gp.new_tile, tracks);
776 if (track == INVALID_TRACK) return ReverseShip(v);
777
778 const ShipSubcoordData &b = _ship_subcoord[diagdir][track];
779
780 gp.x = (gp.x & ~0xF) | b.x_subcoord;
781 gp.y = (gp.y & ~0xF) | b.y_subcoord;
782
783 /* Call the landscape function and tell it that the vehicle entered the tile */
784 auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
785 if (vets.Test(VehicleEnterTileState::CannotEnter)) return ReverseShip(v);
786
788 v->tile = gp.new_tile;
789 v->state = TrackToTrackBits(track);
790
791 /* Update ship cache when the water class changes. Aqueducts are always canals. */
793 }
794
795 const Direction new_direction = b.dir;
796 const DirDiff diff = DirDifference(new_direction, v->direction);
797 switch (diff) {
798 case DIRDIFF_SAME:
799 case DIRDIFF_45RIGHT:
800 case DIRDIFF_45LEFT:
801 /* Continue at speed */
802 v->rotation = v->direction = new_direction;
803 break;
804
805 default:
806 /* Stop for rotation */
807 v->cur_speed = 0;
808 v->direction = new_direction;
809 /* Remember our current location to avoid movement glitch */
810 v->rotation_x_pos = v->x_pos;
811 v->rotation_y_pos = v->y_pos;
812 break;
813 }
814 }
815 } else {
816 /* On a bridge */
818 v->x_pos = gp.x;
819 v->y_pos = gp.y;
820 v->UpdatePosition();
821 if (!v->vehstatus.Test(VehState::Hidden)) v->Vehicle::UpdateViewport(true);
822 continue;
823 }
824
825 /* Ship is back on the bridge head, we need to consume its path
826 * cache entry here as we didn't have to choose a ship track. */
827 if (!v->path.empty()) v->path.pop_back();
828 }
829
830 /* update image of ship, as well as delta XY */
831 v->x_pos = gp.x;
832 v->y_pos = gp.y;
833
834 v->UpdatePosition();
835 v->UpdateViewport(true, true);
836 }
837}
838
840{
842
843 if (!this->vehstatus.Test(VehState::Stopped)) this->running_ticks++;
844
845 ShipController(this);
846
847 return true;
848}
849
850void Ship::SetDestTile(TileIndex tile)
851{
852 if (tile == this->dest_tile) return;
853 this->path.clear();
854 this->dest_tile = tile;
855}
856
866{
867 tile = GetShipDepotNorthTile(tile);
868 if (flags.Test(DoCommandFlag::Execute)) {
869 int x;
870 int y;
871
872 const ShipVehicleInfo *svi = &e->VehInfo<ShipVehicleInfo>();
873
874 Ship *v = new Ship();
875 *ret = v;
876
878 v->tile = tile;
879 x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
880 y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
881 v->x_pos = x;
882 v->y_pos = y;
883 v->z_pos = GetSlopePixelZ(x, y);
884
885 v->direction = DiagDirToDir(GetShipDepotDirection(tile));
886
887 /* UpdateDeltaXY() requires rotation to be initialised as well. */
888 v->rotation = v->direction;
889 v->UpdateDeltaXY();
890
892
893 v->spritenum = svi->image_index;
894 v->cargo_type = e->GetDefaultCargoType();
895 assert(IsValidCargoType(v->cargo_type));
896 v->cargo_cap = svi->capacity;
897 v->refit_cap = 0;
898
899 v->last_station_visited = StationID::Invalid();
900 v->last_loading_station = StationID::Invalid();
901 v->engine_type = e->index;
902
903 v->reliability = e->reliability;
904 v->reliability_spd_dec = e->reliability_spd_dec;
905 v->max_age = e->GetLifeLengthInDays();
906
907 v->state = TRACK_BIT_DEPOT;
908
909 v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
910 v->date_of_last_service = TimerGameEconomy::date;
911 v->date_of_last_service_newgrf = TimerGameCalendar::date;
912 v->build_year = TimerGameCalendar::year;
913 v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
914 v->random_bits = Random();
915
916 v->acceleration = svi->acceleration;
917 v->UpdateCache();
918
920 v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent);
921
922 v->InvalidateNewGRFCacheOfChain();
923
924 v->cargo_cap = e->DetermineCapacity(v);
925
926 v->InvalidateNewGRFCacheOfChain();
927
928 v->UpdatePosition();
929 }
930
931 return CommandCost();
932}
933
935{
936 const Depot *depot = FindClosestShipDepot(this, MAX_SHIP_DEPOT_SEARCH_DISTANCE);
937 if (depot == nullptr) return ClosestDepot();
938
939 return ClosestDepot(depot->xy, depot->index);
940}
Base functions for all AIs.
@ BuiltAsPrototype
Vehicle is a prototype (accepted as exclusive preview).
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:106
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition ai_core.cpp:235
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Reset()
Reset all bits.
Common return value for all commands.
Money GetCost() const
The costs as made up to this moment.
uint16_t reliability_spd_dec
Speed of reliability decay between services (per day).
Definition engine_base.h:50
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
uint DetermineCapacity(const Vehicle *v, uint16_t *mail_capacity=nullptr) const
Determines capacity of a given vehicle from scratch.
Definition engine.cpp:200
EngineFlags flags
Flags of the engine.
Definition engine_base.h:57
uint8_t original_image_index
Original vehicle image index, thus the image index of the overridden vehicle.
Definition engine_base.h:61
TimerGameCalendar::Date GetLifeLengthInDays() const
Returns the vehicle's (not model's!) life length in days.
Definition engine.cpp:442
CargoType GetDefaultCargoType() const
Determines the default cargo type of an engine.
Definition engine_base.h:95
uint16_t reliability
Current reliability of the engine.
Definition engine_base.h:49
Enum-as-bit-set wrapper.
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
RAII class for measuring multi-step elements of performance.
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static constexpr int DAYS_IN_YEAR
days per year
static Date date
Current date in days (day counter).
@ Execute
execute the given command
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
CompanyID _current_company
Company currently doing an action.
void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost &cst)
Subtract money from a company, including the money fraction.
Functions related to companies.
Base for all depots (except hangars)
DepotID GetDepotIndex(Tile t)
Get the index of which depot is attached to the tile.
Definition depot_map.h:53
DirDiff DirDifference(Direction d0, Direction d1)
Calculate the difference between two directions.
Direction DiagDirToDir(DiagDirection dir)
Convert a DiagDirection to a Direction.
Direction ReverseDir(Direction d)
Return the reverse of a direction.
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
Direction ChangeDir(Direction d, DirDiff delta)
Change a direction by a given difference.
DiagDirection DirToDiagDir(Direction dir)
Convert a Direction to a DiagDirection.
DirDiff
Enumeration for the difference between two directions.
@ DIRDIFF_45LEFT
Angle of 45 degrees left.
@ DIRDIFF_REVERSE
One direction is the opposite of the other one.
@ DIRDIFF_45RIGHT
Angle of 45 degrees right.
@ DIRDIFF_SAME
Both directions faces to the same direction.
Direction
Defines the 8 directions on the map.
@ DIR_SW
Southwest.
@ DIR_NW
Northwest.
@ INVALID_DIR
Flag for an invalid direction.
@ DIR_N
North.
@ DIR_SE
Southeast.
@ DIR_S
South.
@ DIR_NE
Northeast.
@ DIR_END
Used to iterate.
@ DIR_W
West.
@ DIR_E
East.
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_END
Used for iterations.
@ DIAGDIR_BEGIN
Used for iterations.
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift)
Determine a certain price.
Definition economy.cpp:949
@ EXPENSES_SHIP_RUN
Running costs ships.
Base class for engines.
@ ExclusivePreview
This vehicle is in the exclusive preview stage, either being used or being offered to a company.
fluid_settings_t * settings
FluidSynth settings handle.
Types for recording game performance data.
@ PFE_GL_SHIPS
Time spent processing ships.
Base functions for all Games.
uint32_t PaletteID
The number of the palette.
Definition gfx_type.h:18
Base of all industries.
Accessors for industries.
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
int GetSlopePixelZ(int x, int y, bool ground_vehicle)
Return world Z coordinate of a given point of a tile.
Functions related to OTTD's landscape.
@ Random
Randomise borders.
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:159
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:142
DiagDirection DiagdirBetweenTiles(TileIndex tile_from, TileIndex tile_to)
Determines the DiagDirection to get from one tile to another.
Definition map_func.h:622
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:610
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:424
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:414
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:569
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
Functions for NewGRF engines.
@ PROP_SHIP_SPEED
Max. speed: 1 unit = 1/3.2 mph = 0.5 km-ish/h.
@ PROP_SHIP_RUNNING_COST_FACTOR
Yearly runningcost.
@ PROP_SHIP_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event, bool force)
Checks whether a NewGRF wants to play a different vehicle sound effect.
Functions related to NewGRF provided sounds.
@ VSE_START
Vehicle starting, i.e. leaving, the station.
Functions related to news.
void AddVehicleNewsItem(EncodedString &&headline, NewsType type, VehicleID vehicle, StationID station=StationID::Invalid())
Adds a newsitem referencing a vehicle.
Definition news_func.h:30
@ ArrivalCompany
First vehicle arrived for company.
@ ArrivalOther
First vehicle arrived for competitor.
bool ProcessOrders(Vehicle *v)
Handle the orders of a vehicle and determine the next place to go to if needed.
void CheckOrders(const Vehicle *v)
Check the orders of a vehicle, to see if there are invalid orders and stuff.
@ ODTFB_SERVICE
This depot order is because of the servicing limit.
Definition order_type.h:110
static const int YAPF_TILE_LENGTH
Length (penalty) of one tile with YAPF.
@ RAIL_GROUND_WATER
Grass with a fence and shore or water on the free halftile.
Definition rail_map.h:498
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
Base for ships.
WaterClass GetEffectiveWaterClass(TileIndex tile)
Determine the effective WaterClass for a ship travelling on a tile.
Definition ship_cmd.cpp:53
constexpr int MAX_SHIP_DEPOT_SEARCH_DISTANCE
Max distance in tiles (as the crow flies) to search for depots when user clicks "go to depot".
Definition ship_cmd.cpp:46
static const ShipSubcoordData _ship_subcoord[DIAGDIR_END][TRACK_END]
Ship sub-coordinate data for moving into a new tile via a Diagdir onto a Track.
Definition ship_cmd.cpp:522
CommandCost CmdBuildShip(DoCommandFlags flags, TileIndex tile, const Engine *e, Vehicle **ret)
Build a ship.
Definition ship_cmd.cpp:865
static uint ShipAccelerate(Vehicle *v)
Accelerates the ship towards its target speed.
Definition ship_cmd.cpp:414
static TrackBits GetAvailShipTracks(TileIndex tile, DiagDirection dir)
Get the available water tracks on a tile for a ship entering a tile.
Definition ship_cmd.cpp:504
static bool ShipMoveUpDownOnLock(Ship *v)
Test and move a ship up or down in a lock.
Definition ship_cmd.cpp:591
bool IsShipDestinationTile(TileIndex tile, StationID station)
Test if a tile is a docking tile for the given station.
Definition ship_cmd.cpp:617
void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
Get the size of the sprite of a ship sprite heading west (used for lists).
Definition ship_cmd.cpp:119
static void ShipArrivesAt(const Vehicle *v, Station *st)
Ship arrives at a dock.
Definition ship_cmd.cpp:439
WaterClass GetEffectiveWaterClass(TileIndex tile)
Determine the effective WaterClass for a ship travelling on a tile.
Definition ship_cmd.cpp:53
static int ShipTestUpDownOnLock(const Ship *v)
Test if a ship is in the centre of a lock and should move up or down.
Definition ship_cmd.cpp:566
static bool CheckShipStayInDepot(Ship *v)
Checks whether a ship should stay in the depot.
Definition ship_cmd.cpp:366
static Track ChooseShipTrack(Ship *v, TileIndex tile, TrackBits tracks)
Runs the pathfinder to choose a track to continue along.
Definition ship_cmd.cpp:465
Command definitions related to ships.
DiagDirection GetInclinedSlopeDirection(Slope s)
Returns the direction of an inclined slope.
Definition slope_func.h:239
Functions related to sound.
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition sprites.h:1619
Base classes/functions for stations.
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition station_map.h:28
bool IsDockTile(Tile t)
Is tile t a dock tile?
bool IsOilRig(Tile t)
Is tile t part of an oilrig?
bool IsDockWaterPart(Tile t)
Check whether a dock tile is the tile on water.
@ HVOT_SHIP
Station has seen a ship.
@ Dock
Station with a dock.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
Functions related to OTTD's strings.
TimerGameTick::Ticks current_order_time
How many ticks have passed since this order started.
TileIndex xy
Base tile of the station.
StationFacilities facilities
The facilities that this station has.
Structure to return information about the closest depot location, and whether it could be found.
T x
X coordinate.
T y
Y coordinate.
PathfinderSettings pf
settings for all pathfinders
Position information of a vehicle after it moved.
TileIndex new_tile
Tile of the vehicle after moving.
int y
x and y position of the vehicle after moving
TileIndex old_tile
Current tile of the vehicle.
Defines the internal data of a functional industry.
Definition industry.h:62
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:251
Station * neutral_station
Associated neutral station.
Definition industry.h:108
Direction last_direction
Last direction we obtained sprites for.
uint16_t GetMaxSpeed() const
Get the maxmimum speed in km-ish/h a vehicle is allowed to reach on the way to the destination.
Definition order_base.h:197
DestinationID GetDestination() const
Gets the destination of this order.
Definition order_base.h:99
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:66
void MakeDummy()
Makes this order a Dummy order.
void MakeLeaveStation()
Makes this order a Leave Station order.
void Free()
'Free' the order
Definition order_cmd.cpp:48
void MakeGoToDepot(DestinationID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type=ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, OrderDepotActionFlags action=ODATF_SERVICE_ONLY, CargoType cargo=CARGO_NO_REFIT)
Makes this order a Go To Depot order.
Definition order_cmd.cpp:74
bool Contains(TileIndex tile) const
Does this tile area contain a tile?
Definition tilearea.cpp:104
YAPFSettings yapf
pathfinder settings for the yet another pathfinder
static Titem * Get(auto index)
Returns Titem with given index.
Tindex index
Index of this pool item.
Specification of a rectangle with absolute coordinates of all edges.
int Width() const
Get width of Rect.
int Height() const
Get height of Rect.
Structure for ship sub-coordinate data for moving into a new tile via a Diagdir onto a Track.
Definition ship_cmd.cpp:512
uint8_t y_subcoord
New Y sub-coordinate on the new tile.
Definition ship_cmd.cpp:514
Direction dir
New Direction to move in on the new track.
Definition ship_cmd.cpp:515
uint8_t x_subcoord
New X sub-coordinate on the new tile.
Definition ship_cmd.cpp:513
Information about a ship vehicle.
Definition engine_type.h:99
uint ApplyWaterClassSpeedFrac(uint raw_speed, bool is_ocean) const
Apply ocean/canal speed fraction to a velocity.
uint16_t max_speed
Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h)
uint8_t acceleration
Acceleration (1 unit = 1/3.2 mph per tick = 0.5 km-ish/h per tick)
All ships have this type.
Definition ship.h:32
bool Tick() override
Calls the tick handler of the vehicle.
Definition ship_cmd.cpp:839
Money GetRunningCost() const override
Gets the running cost of a vehicle.
Definition ship_cmd.cpp:246
TileIndex GetOrderStationLocation(StationID station) override
Determine the location for the station where the vehicle goes to next.
Definition ship_cmd.cpp:317
TrackBits state
The "track" the ship is following.
Definition ship.h:34
int16_t rotation_x_pos
NOSAVE: X Position before rotation.
Definition ship.h:36
Direction rotation
Visible direction.
Definition ship.h:35
void UpdateDeltaXY() override
Updates the x and y offsets and the size of the sprite used for this vehicle.
Definition ship_cmd.cpp:330
void OnNewCalendarDay() override
Calendar day handler.
Definition ship_cmd.cpp:254
int16_t rotation_y_pos
NOSAVE: Y Position before rotation.
Definition ship.h:37
ShipPathCache path
Cached path.
Definition ship.h:33
ClosestDepot FindClosestDepot() override
Find the closest depot for this vehicle and tell us the location, DestinationID and whether we should...
Definition ship_cmd.cpp:934
void MarkDirty() override
Marks the vehicles to be redrawn and updates cached variables.
Definition ship_cmd.cpp:304
Trackdir GetVehicleTrackdir() const override
Returns the Trackdir on which the vehicle is currently located.
Definition ship_cmd.cpp:287
bool IsInDepot() const override
Check whether the vehicle is in the depot.
Definition ship.h:54
void PlayLeaveStationSound(bool force=false) const override
Play the sound associated with leaving the station.
Definition ship_cmd.cpp:311
void OnNewEconomyDay() override
Economy day handler.
Definition ship_cmd.cpp:260
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override
Gets the sprite to show for the given direction.
Definition ship_cmd.cpp:133
void UpdateCache()
Update the caches of this ship.
Definition ship_cmd.cpp:231
static Station * Get(auto index)
Gets station with given index.
void UpdateViewport(bool force_update, bool update_delta)
Update vehicle sprite- and position caches.
Coord3D< int8_t > origin
Position of northern corner within tile.
Definition sprite.h:19
Station data structure.
TileArea docking_station
Tile area the docking tiles cover.
uint16_t cached_cargo_age_period
Number of ticks before carried cargo is aged.
uint16_t cached_max_speed
Maximum speed of the consist (minimum of the max speed of all vehicles in the consist).
Sprite sequence for a vehicle part.
bool IsValid() const
Check whether the sequence contains any sprites.
void GetBounds(Rect *bounds) const
Determine shared bounds of all sprites.
Definition vehicle.cpp:114
void Set(SpriteID sprite)
Assign a single sprite to the sequence.
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const
Draw the sprite sequence.
Definition vehicle.cpp:142
Vehicle data structure.
EngineID engine_type
The type of engine used for this vehicle.
static uint GetAdvanceSpeed(uint speed)
Determines the effective vehicle movement speed.
int32_t z_pos
z coordinate.
Direction direction
facing
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition vehicle.cpp:718
void IncrementRealOrderIndex()
Advanced cur_real_order_index to the next real order, keeps care of the wrap-around and invalidates t...
virtual bool IsChainInDepot() const
Check whether the whole vehicle chain is in the depot.
uint8_t day_counter
Increased by one for each day.
void HandleLoading(bool mode=false)
Handle the loading of the vehicle; when not it skips through dummy orders and does nothing in all oth...
Definition vehicle.cpp:2407
Money profit_this_year
Profit this year << 8, low 8 bits are fract.
SpriteID colourmap
NOSAVE: cached colour mapping.
uint GetAdvanceDistance()
Determines the vehicle "progress" needed for moving a step.
VehStates vehstatus
Status.
void UpdateVisualEffect(bool allow_power_change=true)
Update the cached visual effect.
Definition vehicle.cpp:2636
void LeaveUnbunchingDepot()
Leave an unbunching depot and calculate the next departure time for shared order vehicles.
Definition vehicle.cpp:2486
uint8_t acceleration
used by train & aircraft
Order current_order
The current order (+ status, like: loading)
void HandlePathfindingResult(bool path_found)
Handle the pathfinding result, especially the lost status.
Definition vehicle.cpp:762
int32_t y_pos
y coordinate.
int32_t x_pos
x coordinate.
VehicleCache vcache
Cache of often used vehicle values.
SpriteBounds bounds
Bounding box of vehicle.
void BeginLoading()
Prepare everything to begin the loading when arriving at a station.
Definition vehicle.cpp:2183
uint8_t spritenum
currently displayed sprite index 0xfd == custom sprite, 0xfe == custom second head sprite 0xff == res...
uint16_t cur_speed
current speed
bool IsWaitingForUnbunching() const
Check whether a vehicle inside a depot is waiting for unbunching.
Definition vehicle.cpp:2533
MutableSpriteCache sprite_cache
Cache of sprites and values related to recalculating them, see MutableSpriteCache.
bool HandleBreakdown()
Handle all of the aspects of a vehicle breakdown This includes adding smoke and sounds,...
Definition vehicle.cpp:1332
uint8_t progress
The percentage (if divided by 256) this vehicle already crossed the tile unit.
uint8_t tick_counter
Increased by one for each tick.
TileIndex tile
Current tile index.
TileIndex dest_tile
Heading for this tile.
void UpdatePosition()
Update the position of the vehicle.
Definition vehicle.cpp:1662
StationID last_station_visited
The last station we stopped at.
void ShowVisualEffect() const
Draw visual effects (smoke and/or sparks) for a vehicle chain.
Definition vehicle.cpp:2777
Owner owner
Which company owns the vehicle?
bool NeedsAutomaticServicing() const
Checks if the current order should be interrupted for a service-in-depot order.
Definition vehicle.cpp:283
uint8_t running_ticks
Number of ticks this vehicle was not stopped this day.
Describes a single interconnected patch of water within a particular water region.
int y
The Y coordinate of the water region, i.e. Y=2 is the 3rd water region along the Y-axis.
int x
The X coordinate of the water region, i.e. X=2 is the 3rd water region along the X-axis.
uint32_t maximum_go_to_depot_penalty
What is the maximum penalty that may be endured for going to a depot.
@ CannotEnter
The vehicle cannot enter the tile.
@ EnteredWormhole
The vehicle either entered a bridge, tunnel or depot tile (this includes the last tile of the bridge/...
VehicleEnterTileStates VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
Call the tile callback function for a vehicle entering a tile.
Definition vehicle.cpp:1819
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:136
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:116
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
static constexpr uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in ZOOM_BASE.
Definition tile_type.h:18
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
@ MP_WATER
Water tile.
Definition tile_type.h:54
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
@ MP_INDUSTRY
Part of an industry.
Definition tile_type.h:56
Definition of the game-calendar-timer.
Definition of the game-economy-timer.
Functions related to time tabling.
void UpdateVehicleTimetable(Vehicle *v, bool travelling)
Update the timetable for the vehicle.
Track TrackdirToTrack(Trackdir trackdir)
Returns the Track that a given Trackdir represents.
Definition track_func.h:262
Track TrackToOppositeTrack(Track t)
Find the opposite track to a given track.
Definition track_func.h:231
bool IsDiagonalTrack(Track track)
Checks if a given Track is diagonal.
Definition track_func.h:619
TrackBits TrackToTrackBits(Track track)
Maps a Track to the corresponding TrackBits value.
Definition track_func.h:77
DiagDirection VehicleExitDir(Direction direction, TrackBits track)
Determine the side in which the vehicle will leave the tile.
Definition track_func.h:714
Track TrackBitsToTrack(TrackBits tracks)
Converts TrackBits to Track.
Definition track_func.h:193
Trackdir TrackDirectionToTrackdir(Track track, Direction dir)
Maps a track and a full (8-way) direction to the trackdir that represents the track running in the gi...
Definition track_func.h:498
TrackBits AxisToTrackBits(Axis a)
Maps an Axis to the corresponding TrackBits value.
Definition track_func.h:88
Track FindFirstTrack(TrackBits tracks)
Returns first Track from TrackBits or INVALID_TRACK.
Definition track_func.h:177
TrackBits DiagdirReachesTracks(DiagDirection diagdir)
Returns all tracks that can be reached when entering a tile from a given (diagonal) direction.
Definition track_func.h:573
Trackdir DiagDirToDiagTrackdir(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal trackdir that runs in that direction.
Definition track_func.h:537
TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
Maps a Trackdir to the corresponding TrackdirBits value.
Definition track_func.h:111
TrackBits TrackStatusToTrackBits(TrackStatus ts)
Returns the present-track-information of a TrackStatus.
Definition track_func.h:363
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
Definition track_func.h:439
TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
Discards all directional information from a TrackdirBits value.
Definition track_func.h:308
TrackBits
Allow incrementing of Track variables.
Definition track_type.h:35
@ TRACK_BIT_WORMHOLE
Bitflag for a wormhole (used for tunnels)
Definition track_type.h:52
@ TRACK_BIT_DEPOT
Bitflag for a depot.
Definition track_type.h:53
@ TRACK_BIT_NONE
No track.
Definition track_type.h:36
Trackdir
Enumeration for tracks and directions.
Definition track_type.h:66
@ TRACKDIR_X_NE
X-axis and direction to north-east.
Definition track_type.h:68
@ INVALID_TRACKDIR
Flag for an invalid trackdir.
Definition track_type.h:85
@ TRACKDIR_Y_NW
Y-axis and direction to north-west.
Definition track_type.h:77
Track
These are used to specify a single track.
Definition track_type.h:19
@ INVALID_TRACK
Flag for an invalid track.
Definition track_type.h:28
@ TRACK_END
Used for iterations.
Definition track_type.h:27
@ TRANSPORT_WATER
Transport over water.
Functions that have tunnels and bridges in common.
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
void VehicleEnterDepot(Vehicle *v)
Vehicle entirely entered the depot, update its status, orders, vehicle windows, service it,...
Definition vehicle.cpp:1520
void VehicleServiceInDepot(Vehicle *v)
Service a vehicle and all subsequent vehicles in the consist.
Definition vehicle.cpp:178
GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
Get position information of a vehicle when moving one pixel in the direction it is facing.
Definition vehicle.cpp:1765
void DecreaseVehicleValue(Vehicle *v)
Decrease the value of a vehicle.
Definition vehicle.cpp:1270
void EconomyAgeVehicle(Vehicle *v)
Update economy age of a vehicle.
Definition vehicle.cpp:1398
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition vehicle.cpp:3046
void AgeVehicle(Vehicle *v)
Update age of a vehicle.
Definition vehicle.cpp:1410
@ Crashed
Vehicle is crashed.
@ Hidden
Vehicle is not visible.
@ DefaultPalette
Use default vehicle palette.
@ Stopped
Vehicle is stopped by the player.
Functions related to vehicles.
bool HasVehicleOnTile(TileIndex tile, UnaryPred &&predicate)
Loop over vehicles on a tile, and check whether a predicate is true for any of them.
EngineImageType
Visualisation contexts of vehicles and engines.
@ EIT_ON_MAP
Vehicle drawn in viewport.
@ WID_VV_START_STOP
Start or stop this vehicle, and show information about the current state.
TileIndex GetShipDepotNorthTile(Tile t)
Get the most northern tile of a ship depot.
Definition water_map.h:291
WaterClass
classes of water (for WATER_TILE_CLEAR water tile type).
Definition water_map.h:39
@ WATER_CLASS_SEA
Sea.
Definition water_map.h:40
@ WATER_CLASS_CANAL
Canal.
Definition water_map.h:41
bool HasTileWaterClass(Tile t)
Checks whether the tile has an waterclass associated.
Definition water_map.h:103
bool IsShipDepotTile(Tile t)
Is it a ship depot tile?
Definition water_map.h:234
WaterClass GetWaterClass(Tile t)
Get the water class at a tile.
Definition water_map.h:114
bool IsDockingTile(Tile t)
Checks whether the tile is marked as a dockling tile.
Definition water_map.h:373
@ LOCK_PART_MIDDLE
Middle part of a lock.
Definition water_map.h:66
bool IsLock(Tile t)
Is there a lock on a given water tile?
Definition water_map.h:305
DiagDirection GetShipDepotDirection(Tile t)
Get the direction of the ship depot.
Definition water_map.h:269
LockPart GetLockPart(Tile t)
Get the part of a lock.
Definition water_map.h:328
Axis GetShipDepotAxis(Tile t)
Get the axis of the ship depot.
Definition water_map.h:245
WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile)
Returns basic water region patch information for the provided tile.
int CalculateWaterRegionPatchHash(const WaterRegionPatchDesc &water_region_patch)
Calculates a number that uniquely identifies the provided water region patch.
void VisitWaterRegionPatchNeighbours(const WaterRegionPatchDesc &water_region_patch, VisitWaterRegionPatchCallback &callback)
Calls the provided callback function on all accessible water region patches in each cardinal directio...
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3184
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition window.cpp:3276
void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, WidgetID widget_index)
Mark a particular widget in a particular window as dirty (in need of repainting)
Definition window.cpp:3171
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3158
Window functions not directly related to making/drawing windows.
@ WC_VEHICLE_DEPOT
Depot view; Window numbers:
@ WC_SHIPS_LIST
Ships list; Window numbers:
@ WC_VEHICLE_DETAILS
Vehicle details; Window numbers:
@ WC_VEHICLE_VIEW
Vehicle view; Window numbers:
Entry point for OpenTTD to YAPF.
bool YapfShipCheckReverse(const Ship *v, Trackdir *trackdir)
Returns true if it is better to reverse the ship before leaving depot using YAPF.
Track YapfShipChooseTrack(const Ship *v, TileIndex tile, bool &path_found, ShipPathCache &path_cache)
Finds the best path for given ship using YAPF.
Implementation of YAPF for water regions, which are used for finding intermediate ship destinations.
Functions related to zooming.
int UnScaleGUI(int value)
Short-hand to apply GUI zoom level.
Definition zoom_func.h:77