OpenTTD Source 20260421-master-gc2fbc6fdeb
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
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);
58 return WaterClass::Canal;
59 }
60 if (IsTileType(tile, TileType::Railway)) {
62 return WaterClass::Sea;
63 }
64 NOT_REACHED();
65}
66
67static const uint16_t _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
68
70template <>
71bool IsValidImageIndex<VEH_SHIP>(uint8_t image_index)
72{
73 return image_index < lengthof(_ship_sprites);
74}
75
76static inline TrackBits GetTileShipTrackStatus(TileIndex tile)
77{
79}
80
81static void GetShipIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result)
82{
83 const Engine *e = Engine::Get(engine);
84 uint8_t spritenum = e->VehInfo<ShipVehicleInfo>().image_index;
85
86 if (IsCustomVehicleSpriteNum(spritenum)) {
87 GetCustomVehicleIcon(engine, DIR_W, image_type, result);
88 if (result->IsValid()) return;
89
90 spritenum = e->original_image_index;
91 }
92
93 assert(IsValidImageIndex<VEH_SHIP>(spritenum));
94 result->Set(DIR_W + _ship_sprites[spritenum]);
95}
96
97void DrawShipEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
98{
100 GetShipIcon(engine, image_type, &seq);
101
102 Rect rect;
103 seq.GetBounds(&rect);
104 preferred_x = Clamp(preferred_x,
105 left - UnScaleGUI(rect.left),
106 right - UnScaleGUI(rect.right));
107
108 seq.Draw(preferred_x, y, pal, pal == PALETTE_CRASH);
109}
110
120void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
121{
123 GetShipIcon(engine, image_type, &seq);
124
125 Rect rect;
126 seq.GetBounds(&rect);
127
128 width = UnScaleGUI(rect.Width());
129 height = UnScaleGUI(rect.Height());
130 xoffs = UnScaleGUI(rect.left);
131 yoffs = UnScaleGUI(rect.top);
132}
133
135{
136 uint8_t spritenum = this->spritenum;
137
138 if (image_type == EIT_ON_MAP) direction = this->rotation;
139
140 if (IsCustomVehicleSpriteNum(spritenum)) {
141 GetCustomVehicleSprite(this, direction, image_type, result);
142 if (result->IsValid()) return;
143
145 }
146
148 result->Set(_ship_sprites[spritenum] + direction);
149}
150
151static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)
152{
153 const int max_region_distance = (max_distance / WATER_REGION_EDGE_LENGTH) + 1;
154
155 static std::unordered_set<int> visited_patch_hashes;
156 static std::deque<WaterRegionPatchDesc> patches_to_search;
157 visited_patch_hashes.clear();
158 patches_to_search.clear();
159
160 /* Step 1: find a set of reachable Water Region Patches using BFS. */
161 const WaterRegionPatchDesc start_patch = GetWaterRegionPatchInfo(v->tile);
162 patches_to_search.push_back(start_patch);
163 visited_patch_hashes.insert(CalculateWaterRegionPatchHash(start_patch));
164
165 while (!patches_to_search.empty()) {
166 /* Remove first patch from the queue and make it the current patch. */
167 const WaterRegionPatchDesc current_node = patches_to_search.front();
168 patches_to_search.pop_front();
169
170 /* Add neighbours of the current patch to the search queue. */
171 VisitWaterRegionPatchCallback visit_func = [&](const WaterRegionPatchDesc &water_region_patch) {
172 /* Note that we check the max distance per axis, not the total distance. */
173 if (std::abs(water_region_patch.x - start_patch.x) > max_region_distance ||
174 std::abs(water_region_patch.y - start_patch.y) > max_region_distance) return;
175
176 const int hash = CalculateWaterRegionPatchHash(water_region_patch);
177 if (visited_patch_hashes.count(hash) == 0) {
178 visited_patch_hashes.insert(hash);
179 patches_to_search.push_back(water_region_patch);
180 }
181 };
182
183 VisitWaterRegionPatchNeighbours(current_node, visit_func);
184 }
185
186 /* Step 2: Find the closest depot within the reachable Water Region Patches. */
187 const Depot *best_depot = nullptr;
188 uint best_dist_sq = std::numeric_limits<uint>::max();
189 for (const Depot *depot : Depot::Iterate()) {
190 const TileIndex tile = depot->xy;
191 if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) {
192 const uint dist_sq = DistanceSquare(tile, v->tile);
193 if (dist_sq < best_dist_sq && dist_sq <= max_distance * max_distance &&
194 visited_patch_hashes.count(CalculateWaterRegionPatchHash(GetWaterRegionPatchInfo(tile))) > 0) {
195 best_dist_sq = dist_sq;
196 best_depot = depot;
197 }
198 }
199 }
200
201 return best_depot;
202}
203
204static void CheckIfShipNeedsService(Vehicle *v)
205{
206 if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
207 if (v->IsChainInDepot()) {
209 return;
210 }
211
212 uint max_distance = _settings_game.pf.yapf.maximum_go_to_depot_penalty / YAPF_TILE_LENGTH;
213
214 const Depot *depot = FindClosestShipDepot(v, max_distance);
215
216 if (depot == nullptr) {
217 if (v->current_order.IsType(OT_GOTO_DEPOT)) {
220 }
221 return;
222 }
223
225 v->SetDestTile(depot->xy);
227}
228
233{
234 const ShipVehicleInfo *svi = ShipVehInfo(this->engine_type);
235
236 /* Get speed fraction for the current water type. Aqueducts are always canals. */
237 bool is_ocean = GetEffectiveWaterClass(this->tile) == WaterClass::Sea;
238 uint raw_speed = GetVehicleProperty(this, PROP_SHIP_SPEED, svi->max_speed);
239 this->vcache.cached_max_speed = svi->ApplyWaterClassSpeedFrac(raw_speed, is_ocean);
240
241 /* Update cargo aging period. */
242 this->vcache.cached_cargo_age_period = GetVehicleProperty(this, PROP_SHIP_CARGO_AGE_PERIOD, EngInfo(this->engine_type)->cargo_age_period);
243
244 this->UpdateVisualEffect();
245}
246
248{
249 const Engine *e = this->GetEngine();
250 uint cost_factor = GetVehicleProperty(this, PROP_SHIP_RUNNING_COST_FACTOR, e->VehInfo<ShipVehicleInfo>().running_cost);
251 return GetPrice(Price::RunningShip, cost_factor, e->GetGRF());
252}
253
256{
257 AgeVehicle(this);
258}
259
262{
263 EconomyAgeVehicle(this);
264
265 if ((++this->day_counter & 7) == 0) {
267 }
268
270 CheckIfShipNeedsService(this);
271
272 CheckOrders(this);
273
274 if (this->running_ticks == 0) return;
275
277
278 this->profit_this_year -= cost.GetCost();
279 this->running_ticks = 0;
280
282
284 /* we need this for the profit */
286}
287
289{
290 if (this->vehstatus.Test(VehState::Crashed)) return INVALID_TRACKDIR;
291
292 if (this->IsInDepot()) {
293 /* We'll assume the ship is facing outwards */
295 }
296
297 if (this->state == TRACK_BIT_WORMHOLE) {
298 /* ship on aqueduct, so just use its direction and assume a diagonal track */
300 }
301
303}
304
306{
307 this->colourmap = PAL_NONE;
308 this->UpdateViewport(true, false);
309 this->UpdateCache();
310}
311
312void Ship::PlayLeaveStationSound(bool force) const
313{
314 if (PlayVehicleSound(this, VSE_START, force)) return;
315 SndPlayVehicleFx(ShipVehInfo(this->engine_type)->sfx, this);
316}
317
319{
320 if (station == this->last_station_visited) this->last_station_visited = StationID::Invalid();
321
322 const Station *st = Station::Get(station);
323 if (CanVehicleUseStation(this, st)) {
324 return st->xy;
325 } else {
327 return TileIndex{};
328 }
329}
330
332{
333 static constexpr SpriteBounds ship_bounds[DIR_END] = {
334 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // N
335 {{-16, -3, 0}, {32, 6, 6}, {}}, // NE
336 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // E
337 {{ -3, -16, 0}, { 6, 32, 6}, {}}, // SE
338 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // S
339 {{-16, -3, 0}, {32, 6, 6}, {}}, // SW
340 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // W
341 {{ -3, -16, 0}, { 6, 32, 6}, {}}, // NW
342 };
343
344 this->bounds = ship_bounds[this->rotation];
345
346 if (this->direction != this->rotation) {
347 /* If we are rotating, then it is possible the ship was moved to its next position. In that
348 * case, because we are still showing the old direction, the ship will appear to glitch sideways
349 * slightly. We can work around this by applying an additional offset to make the ship appear
350 * where it was before it moved. */
351 this->bounds.origin.x -= this->x_pos - this->rotation_x_pos;
352 this->bounds.origin.y -= this->y_pos - this->rotation_y_pos;
353 }
354}
355
356static bool CheckReverseShip(const Ship *v, Trackdir *trackdir = nullptr)
357{
358 /* Ask pathfinder for best direction */
359 return YapfShipCheckReverse(v, trackdir);
360}
361
368{
369 if (!v->IsChainInDepot()) return false;
370
371 /* Check if we should wait here for unbunching. */
372 if (v->IsWaitingForUnbunching()) return true;
373
374 /* We are leaving a depot, but have to go to the exact same one; re-enter */
375 if (v->current_order.IsType(OT_GOTO_DEPOT) &&
378 return true;
379 }
380
381 /* Don't leave depot if no destination set */
382 if (v->dest_tile == INVALID_TILE) return true;
383
384 /* Don't leave depot if another vehicle is already entering/leaving */
385 /* This helps avoid CPU load if many ships are set to start at the same time */
386 if (HasVehicleOnTile(v->tile, [](const Vehicle *u) {
387 return u->type == VEH_SHIP && u->cur_speed != 0;
388 })) return true;
389
392 if (CheckReverseShip(v)) v->direction = ReverseDir(v->direction);
393
395 v->rotation = v->direction;
397 v->cur_speed = 0;
398 v->UpdateViewport(true, true);
400
406
407 return false;
408}
409
415static uint ShipAccelerate(Vehicle *v)
416{
417 uint speed;
418 speed = std::min<uint>(v->cur_speed + v->acceleration, v->vcache.cached_max_speed);
419 speed = std::min<uint>(speed, v->current_order.GetMaxSpeed() * 2);
420
421 /* updates statusbar only if speed have changed to save CPU time */
422 if (speed != v->cur_speed) {
423 v->cur_speed = speed;
425 }
426
427 const uint advance_speed = v->GetAdvanceSpeed(speed);
428 const uint number_of_steps = (advance_speed + v->progress) / v->GetAdvanceDistance();
429 const uint remainder = (advance_speed + v->progress) % v->GetAdvanceDistance();
430 assert(remainder <= std::numeric_limits<uint8_t>::max());
431 v->progress = static_cast<uint8_t>(remainder);
432 return number_of_steps;
433}
434
440static void ShipArrivesAt(const Vehicle *v, Station *st)
441{
442 /* Check if station was ever visited before */
443 if (!(st->had_vehicle_of_type & HVOT_SHIP)) {
444 st->had_vehicle_of_type |= HVOT_SHIP;
445
447 GetEncodedString(STR_NEWS_FIRST_SHIP_ARRIVAL, st->index),
449 v->index,
450 st->index
451 );
452 AI::NewEvent(v->owner, new ScriptEventStationFirstVehicle(st->index, v->index));
453 Game::NewEvent(new ScriptEventStationFirstVehicle(st->index, v->index));
454 }
455}
456
457
467{
468 bool path_found = true;
469 Track track;
470
471 if (v->dest_tile == INVALID_TILE) {
472 /* No destination, don't invoke pathfinder. */
473 track = TrackBitsToTrack(v->state);
474 if (!IsDiagonalTrack(track)) track = TrackToOppositeTrack(track);
475 if (!HasBit(tracks, track)) track = FindFirstTrack(tracks);
476 path_found = false;
477 } else {
478 /* Attempt to follow cached path. */
479 if (!v->path.empty()) {
480 track = TrackdirToTrack(v->path.back().trackdir);
481
482 if (HasBit(tracks, track)) {
483 v->path.pop_back();
484 /* HandlePathfindResult() is not called here because this is not a new pathfinder result. */
485 return track;
486 }
487
488 /* Cached path is invalid so continue with pathfinder. */
489 v->path.clear();
490 }
491
492 track = YapfShipChooseTrack(v, tile, path_found, v->path);
493 }
494
495 v->HandlePathfindingResult(path_found);
496 return track;
497}
498
506{
507 TrackBits tracks = GetTileShipTrackStatus(tile) & DiagdirReachesTracks(dir);
508
509 return tracks;
510}
511
518
524 /* DIAGDIR_NE */
525 {
526 {15, 8, DIR_NE}, // TRACK_X
527 { 0, 0, INVALID_DIR}, // TRACK_Y
528 { 0, 0, INVALID_DIR}, // TRACK_UPPER
529 {15, 8, DIR_E}, // TRACK_LOWER
530 {15, 7, DIR_N}, // TRACK_LEFT
531 { 0, 0, INVALID_DIR}, // TRACK_RIGHT
532 },
533 /* DIAGDIR_SE */
534 {
535 { 0, 0, INVALID_DIR}, // TRACK_X
536 { 8, 0, DIR_SE}, // TRACK_Y
537 { 7, 0, DIR_E}, // TRACK_UPPER
538 { 0, 0, INVALID_DIR}, // TRACK_LOWER
539 { 8, 0, DIR_S}, // TRACK_LEFT
540 { 0, 0, INVALID_DIR}, // TRACK_RIGHT
541 },
542 /* DIAGDIR_SW */
543 {
544 { 0, 8, DIR_SW}, // TRACK_X
545 { 0, 0, INVALID_DIR}, // TRACK_Y
546 { 0, 7, DIR_W}, // TRACK_UPPER
547 { 0, 0, INVALID_DIR}, // TRACK_LOWER
548 { 0, 0, INVALID_DIR}, // TRACK_LEFT
549 { 0, 8, DIR_S}, // TRACK_RIGHT
550 },
551 /* DIAGDIR_NW */
552 {
553 { 0, 0, INVALID_DIR}, // TRACK_X
554 { 8, 15, DIR_NW}, // TRACK_Y
555 { 0, 0, INVALID_DIR}, // TRACK_UPPER
556 { 8, 15, DIR_W}, // TRACK_LOWER
557 { 0, 0, INVALID_DIR}, // TRACK_LEFT
558 { 7, 15, DIR_N}, // TRACK_RIGHT
559 }
560};
561
567static int ShipTestUpDownOnLock(const Ship *v)
568{
569 /* Suitable tile? */
570 if (!IsTileType(v->tile, TileType::Water) || !IsLock(v->tile) || GetLockPart(v->tile) != LockPart::Middle) return 0;
571
572 /* Must be at the centre of the lock */
573 if ((v->x_pos & 0xF) != 8 || (v->y_pos & 0xF) != 8) return 0;
574
576 assert(IsValidDiagDirection(diagdir));
577
578 if (DirToDiagDir(v->direction) == diagdir) {
579 /* Move up */
580 return (v->z_pos < GetTileMaxZ(v->tile) * (int)TILE_HEIGHT) ? 1 : 0;
581 } else {
582 /* Move down */
583 return (v->z_pos > GetTileZ(v->tile) * (int)TILE_HEIGHT) ? -1 : 0;
584 }
585}
586
593{
594 /* Moving up/down through lock */
595 int dz = ShipTestUpDownOnLock(v);
596 if (dz == 0) return false;
597
598 if (v->cur_speed != 0) {
599 v->cur_speed = 0;
601 }
602
603 if ((v->tick_counter & 7) == 0) {
604 v->z_pos += dz;
605 v->UpdatePosition();
606 v->UpdateViewport(true, true);
607 }
608
609 return true;
610}
611
618bool IsShipDestinationTile(TileIndex tile, StationID station)
619{
620 assert(IsDockingTile(tile));
621 /* Check each tile adjacent to docking tile. */
622 for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) {
623 TileIndex t = tile + TileOffsByDiagDir(d);
624 if (!IsValidTile(t)) continue;
625 if (IsDockTile(t) && GetStationIndex(t) == station && IsDockWaterPart(t)) return true;
627 const Industry *i = Industry::GetByTile(t);
628 if (i->neutral_station != nullptr && i->neutral_station->index == station) return true;
629 }
630 if (IsTileType(t, TileType::Station) && IsOilRig(t) && GetStationIndex(t) == station) return true;
631 }
632 return false;
633}
634
635static void ReverseShipIntoTrackdir(Ship *v, Trackdir trackdir)
636{
637 static constexpr Direction _trackdir_to_direction[] = {
640 };
641
642 v->direction = _trackdir_to_direction[trackdir];
643 assert(v->direction != INVALID_DIR);
645
646 /* Remember our current location to avoid movement glitch */
647 v->rotation_x_pos = v->x_pos;
648 v->rotation_y_pos = v->y_pos;
649 v->cur_speed = 0;
650 v->path.clear();
651
652 v->UpdatePosition();
653 v->UpdateViewport(true, true);
654}
655
656static void ReverseShip(Ship *v)
657{
659
660 /* Remember our current location to avoid movement glitch */
661 v->rotation_x_pos = v->x_pos;
662 v->rotation_y_pos = v->y_pos;
663 v->cur_speed = 0;
664 v->path.clear();
665
666 v->UpdatePosition();
667 v->UpdateViewport(true, true);
668}
669
670static void ShipController(Ship *v)
671{
672 v->tick_counter++;
674
675 if (v->HandleBreakdown()) return;
676
677 if (v->vehstatus.Test(VehState::Stopped)) return;
678
679 if (ProcessOrders(v) && CheckReverseShip(v)) return ReverseShip(v);
680
681 v->HandleLoading();
682
683 if (v->current_order.IsType(OT_LOADING)) return;
684
685 if (CheckShipStayInDepot(v)) return;
686
687 v->ShowVisualEffect();
688
689 /* Rotating on spot */
690 if (v->direction != v->rotation) {
691 if ((v->tick_counter & 7) == 0) {
694 /* Invalidate the sprite cache direction to force recalculation of viewport */
696 v->UpdateViewport(true, true);
697 }
698 return;
699 }
700
701 if (ShipMoveUpDownOnLock(v)) return;
702
703 const uint number_of_steps = ShipAccelerate(v);
704 for (uint i = 0; i < number_of_steps; ++i) {
705 if (ShipMoveUpDownOnLock(v)) return;
706
708 if (v->state != TRACK_BIT_WORMHOLE) {
709 /* Not on a bridge */
710 if (gp.old_tile == gp.new_tile) {
711 /* Staying in tile */
712 if (v->IsInDepot()) {
713 gp.x = v->x_pos;
714 gp.y = v->y_pos;
715 } else {
716 /* Not inside depot */
717 auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
718 if (vets.Test(VehicleEnterTileState::CannotEnter)) return ReverseShip(v);
719
720 /* A leave station order only needs one tick to get processed, so we can
721 * always skip ahead. */
722 if (v->current_order.IsType(OT_LEAVESTATION)) {
723 v->current_order.Free();
725 /* Test if continuing forward would lead to a dead-end, moving into the dock. */
726 const DiagDirection exitdir = VehicleExitDir(v->direction, v->state);
727 const TileIndex tile = TileAddByDiagDir(v->tile, exitdir);
729 } else if (v->dest_tile != INVALID_TILE) {
730 /* We have a target, let's see if we reached it... */
731 if (v->current_order.IsType(OT_GOTO_WAYPOINT) &&
732 DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
733 /* We got within 3 tiles of our target buoy, so let's skip to our
734 * next order */
735 UpdateVehicleTimetable(v, true);
738 } else if (v->current_order.IsType(OT_GOTO_DEPOT) &&
739 v->dest_tile == gp.new_tile) {
740 /* Depot orders really need to reach the tile */
741 if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) {
743 return;
744 }
745 } else if (v->current_order.IsType(OT_GOTO_STATION) && IsDockingTile(gp.new_tile)) {
746 /* Process station in the orderlist. */
747 Station *st = Station::Get(v->current_order.GetDestination().ToStationID());
748 if (st->docking_station.Contains(gp.new_tile) && IsShipDestinationTile(gp.new_tile, st->index)) {
749 v->last_station_visited = st->index;
750 if (st->facilities.Test(StationFacility::Dock)) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
751 ShipArrivesAt(v, st);
752 v->BeginLoading();
753 } else { // leave stations without docks right away
756 }
757 }
758 }
759 }
760 }
761 } else {
762 /* New tile */
763 if (!IsValidTile(gp.new_tile)) return ReverseShip(v);
764
765 const DiagDirection diagdir = DiagdirBetweenTiles(gp.old_tile, gp.new_tile);
766 assert(diagdir != INVALID_DIAGDIR);
767 const TrackBits tracks = GetAvailShipTracks(gp.new_tile, diagdir);
768 if (tracks == TRACK_BIT_NONE) {
769 Trackdir trackdir = INVALID_TRACKDIR;
770 CheckReverseShip(v, &trackdir);
771 if (trackdir == INVALID_TRACKDIR) return ReverseShip(v);
772 return ReverseShipIntoTrackdir(v, trackdir);
773 }
774
775 /* Choose a direction, and continue if we find one */
776 const Track track = ChooseShipTrack(v, gp.new_tile, tracks);
777 if (track == INVALID_TRACK) return ReverseShip(v);
778
779 const ShipSubcoordData &b = _ship_subcoord[diagdir][track];
780
781 gp.x = (gp.x & ~0xF) | b.x_subcoord;
782 gp.y = (gp.y & ~0xF) | b.y_subcoord;
783
784 /* Call the landscape function and tell it that the vehicle entered the tile */
785 auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
786 if (vets.Test(VehicleEnterTileState::CannotEnter)) return ReverseShip(v);
787
789 v->tile = gp.new_tile;
790 v->state = TrackToTrackBits(track);
791
792 /* Update ship cache when the water class changes. Aqueducts are always canals. */
794 }
795
796 const Direction new_direction = b.dir;
797 const DirDiff diff = DirDifference(new_direction, v->direction);
798 switch (diff) {
799 case DIRDIFF_SAME:
800 case DIRDIFF_45RIGHT:
801 case DIRDIFF_45LEFT:
802 /* Continue at speed */
803 v->rotation = v->direction = new_direction;
804 break;
805
806 default:
807 /* Stop for rotation */
808 v->cur_speed = 0;
809 v->direction = new_direction;
810 /* Remember our current location to avoid movement glitch */
811 v->rotation_x_pos = v->x_pos;
812 v->rotation_y_pos = v->y_pos;
813 break;
814 }
815 }
816 } else {
817 /* On a bridge */
819 v->x_pos = gp.x;
820 v->y_pos = gp.y;
821 v->UpdatePosition();
822 if (!v->vehstatus.Test(VehState::Hidden)) v->Vehicle::UpdateViewport(true);
823 continue;
824 }
825
826 /* Ship is back on the bridge head, we need to consume its path
827 * cache entry here as we didn't have to choose a ship track. */
828 if (!v->path.empty()) v->path.pop_back();
829 }
830
831 /* update image of ship, as well as delta XY */
832 v->x_pos = gp.x;
833 v->y_pos = gp.y;
834
835 v->UpdatePosition();
836 v->UpdateViewport(true, true);
837 }
838}
839
841{
843
844 if (!this->vehstatus.Test(VehState::Stopped)) this->running_ticks++;
845
846 ShipController(this);
847
848 return true;
849}
850
852{
853 if (tile == this->dest_tile) return;
854 this->path.clear();
855 this->dest_tile = tile;
856}
857
866CommandCost CmdBuildShip(DoCommandFlags flags, TileIndex tile, const Engine *e, Vehicle **ret)
867{
868 tile = GetShipDepotNorthTile(tile);
869 if (flags.Test(DoCommandFlag::Execute)) {
870 int x;
871 int y;
872
873 const ShipVehicleInfo *svi = &e->VehInfo<ShipVehicleInfo>();
874
875 Ship *v = Ship::Create();
876 *ret = v;
877
879 v->tile = tile;
880 x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
881 y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
882 v->x_pos = x;
883 v->y_pos = y;
884 v->z_pos = GetSlopePixelZ(x, y);
885
886 v->direction = DiagDirToDir(GetShipDepotDirection(tile));
887
888 /* UpdateDeltaXY() requires rotation to be initialised as well. */
889 v->rotation = v->direction;
890 v->UpdateDeltaXY();
891
893
894 v->spritenum = svi->image_index;
895 v->cargo_type = e->GetDefaultCargoType();
896 assert(IsValidCargoType(v->cargo_type));
897 v->cargo_cap = svi->capacity;
898 v->refit_cap = 0;
899
900 v->last_station_visited = StationID::Invalid();
901 v->last_loading_station = StationID::Invalid();
902 v->engine_type = e->index;
903
904 v->reliability = e->reliability;
905 v->reliability_spd_dec = e->reliability_spd_dec;
906 v->max_age = e->GetLifeLengthInDays();
907
908 v->state = TRACK_BIT_DEPOT;
909
910 v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
911 v->date_of_last_service = TimerGameEconomy::date;
912 v->date_of_last_service_newgrf = TimerGameCalendar::date;
913 v->build_year = TimerGameCalendar::year;
914 v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
915 v->random_bits = Random();
916
917 v->acceleration = svi->acceleration;
918 v->UpdateCache();
919
921 v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent);
922
923 v->InvalidateNewGRFCacheOfChain();
924
925 v->cargo_cap = e->DetermineCapacity(v);
926
927 v->InvalidateNewGRFCacheOfChain();
928
929 v->UpdatePosition();
930 }
931
932 return CommandCost();
933}
934
936{
937 const Depot *depot = FindClosestShipDepot(this, MAX_SHIP_DEPOT_SEARCH_DISTANCE);
938 if (depot == nullptr) return ClosestDepot();
939
940 return ClosestDepot(depot->xy, depot->index);
941}
Base functions for all AIs.
@ BuiltAsPrototype
Vehicle is a prototype (accepted as exclusive preview).
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:108
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:204
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:446
CargoType GetDefaultCargoType() const
Determines the default cargo type of an engine.
Definition engine_base.h:94
uint16_t reliability
Current reliability of the engine.
Definition engine_base.h:49
static void NewEvent(class ScriptEvent *event)
Queue a new event for the 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 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:56
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:940
@ EXPENSES_SHIP_RUN
Running costs ships.
@ RunningShip
Running cost of ships.
Base class for engines.
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF > EngineID
Unique identification number of an engine.
Definition engine_type.h:26
@ 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 to map for industries.
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, RoadTramType 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.
#define Rect
Macro that prevents name conflicts between included headers.
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:186
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:169
DiagDirection DiagdirBetweenTiles(TileIndex tile_from, TileIndex tile_to)
Determines the DiagDirection to get from one tile to another.
Definition map_func.h:627
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:615
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:429
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:419
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:574
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:32
@ ArrivalCompany
First vehicle arrived for company.
Definition news_type.h:30
@ ArrivalOther
First vehicle arrived for competitor.
Definition news_type.h:31
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.
@ Service
This depot order is because of the servicing limit.
Definition order_type.h:108
static const int YAPF_TILE_LENGTH
Length (penalty) of one tile with YAPF.
RailGroundType GetRailGroundType(Tile t)
Get the ground type for rail tiles.
Definition rail_map.h:591
@ HalfTileWater
Grass with a fence and shore or water on the free halftile.
Definition rail_map.h:572
@ Invalid
Invalid marker.
Definition road_type.h:41
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.
bool IsShipDestinationTile(TileIndex tile, StationID station)
Test if a tile is a docking tile for the given station.
Definition ship_cmd.cpp:618
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:523
CommandCost CmdBuildShip(DoCommandFlags flags, TileIndex tile, const Engine *e, Vehicle **ret)
Build a ship.
Definition ship_cmd.cpp:866
static uint ShipAccelerate(Vehicle *v)
Accelerates the ship towards its target speed.
Definition ship_cmd.cpp:415
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:505
static bool ShipMoveUpDownOnLock(Ship *v)
Test and move a ship up or down in a lock.
Definition ship_cmd.cpp:592
bool IsShipDestinationTile(TileIndex tile, StationID station)
Test if a tile is a docking tile for the given station.
Definition ship_cmd.cpp:618
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:120
bool IsValidImageIndex< VEH_SHIP >(uint8_t image_index)
Helper to check whether an image index is valid for a particular vehicle.
Definition ship_cmd.cpp:71
static void ShipArrivesAt(const Vehicle *v, Station *st)
Ship arrives at a dock.
Definition ship_cmd.cpp:440
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:567
static bool CheckShipStayInDepot(Ship *v)
Checks whether a ship should stay in the depot.
Definition ship_cmd.cpp:367
static Track ChooseShipTrack(Ship *v, TileIndex tile, TrackBits tracks)
Runs the pathfinder to choose a track to continue along.
Definition ship_cmd.cpp:466
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.
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:307
DestinationID GetDestination() const
Gets the destination of this order.
Definition order_base.h:100
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:67
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:47
void MakeGoToDepot(DestinationID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type=OrderNonStopFlag::NonStop, OrderDepotActionFlags action={}, CargoType cargo=CARGO_NO_REFIT)
Makes this order a Go To Depot order.
Definition order_cmd.cpp:73
bool Contains(TileIndex tile) const
Does this tile area contain a tile?
Definition tilearea.cpp:104
static Pool::IterateWrapper< Depot > Iterate(size_t from=0)
static Engine * Get(auto index)
static T * Create(Targs &&... args)
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:513
uint8_t y_subcoord
New Y sub-coordinate on the new tile.
Definition ship_cmd.cpp:515
Direction dir
New Direction to move in on the new track.
Definition ship_cmd.cpp:516
uint8_t x_subcoord
New X sub-coordinate on the new tile.
Definition ship_cmd.cpp:514
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:840
Money GetRunningCost() const override
Gets the running cost of a vehicle.
Definition ship_cmd.cpp:247
TileIndex GetOrderStationLocation(StationID station) override
Determine the location for the station where the vehicle goes to next.
Definition ship_cmd.cpp:318
void SetDestTile(TileIndex tile) override
Set the destination of this vehicle.
Definition ship_cmd.cpp:851
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:331
void OnNewCalendarDay() override
Calendar day handler.
Definition ship_cmd.cpp:255
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:935
void MarkDirty() override
Marks the vehicles to be redrawn and updates cached variables.
Definition ship_cmd.cpp:305
Trackdir GetVehicleTrackdir() const override
Returns the Trackdir on which the vehicle is currently located.
Definition ship_cmd.cpp:288
bool IsInDepot() const override
Check whether the vehicle is in the depot.
Definition ship.h:53
void PlayLeaveStationSound(bool force=false) const override
Play the sound associated with leaving the station.
Definition ship_cmd.cpp:312
void OnNewEconomyDay() override
Economy day handler.
Definition ship_cmd.cpp:261
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override
Gets the sprite to show for the given direction.
Definition ship_cmd.cpp:134
void UpdateCache()
Update the caches of this ship.
Definition ship_cmd.cpp:232
static Station * Get(auto index)
void UpdateViewport(bool force_update, bool update_delta)
Station data structure.
TileArea docking_station
Tile area the docking tiles cover.
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:123
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:151
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:748
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.
virtual void SetDestTile(TileIndex tile)
Set the destination of this vehicle.
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:2450
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:2680
void LeaveUnbunchingDepot()
Leave an unbunching depot and calculate the next departure time for shared order vehicles.
Definition vehicle.cpp:2530
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:792
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:2224
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:2577
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:1377
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:1703
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:2821
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:292
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.
@ CannotEnter
The vehicle cannot enter the tile.
Definition tile_cmd.h:27
@ EnteredWormhole
The vehicle either entered a bridge, tunnel or depot tile (this includes the last tile of the bridge/...
Definition tile_cmd.h:26
VehicleEnterTileStates VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
Call the tile callback function for a vehicle entering a tile.
Definition vehicle.cpp:1860
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:135
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:115
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
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
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
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
@ TunnelBridge
Tunnel entry/exit and bridge heads.
Definition tile_type.h:58
@ Water
Water tile.
Definition tile_type.h:55
@ Station
A tile of a station or airport.
Definition tile_type.h:54
@ Industry
Part of an industry.
Definition tile_type.h:57
@ Railway
A tile with railway.
Definition tile_type.h:50
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:624
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:719
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:503
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:578
Trackdir DiagDirToDiagTrackdir(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal trackdir that runs in that direction.
Definition track_func.h:542
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:365
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
Definition track_func.h:441
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:1565
void VehicleServiceInDepot(Vehicle *v)
Service a vehicle and all subsequent vehicles in the consist.
Definition vehicle.cpp:187
void CheckVehicleBreakdown(Vehicle *v)
Periodic check for a vehicle to maybe break down.
Definition vehicle.cpp:1321
GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
Get position information of a vehicle when moving one pixel in the direction it is facing.
Definition vehicle.cpp:1806
void DecreaseVehicleValue(Vehicle *v)
Decrease the value of a vehicle.
Definition vehicle.cpp:1300
void EconomyAgeVehicle(Vehicle *v)
Update economy age of a vehicle.
Definition vehicle.cpp:1443
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition vehicle.cpp:3098
void AgeVehicle(Vehicle *v)
Update age of a vehicle.
Definition vehicle.cpp:1455
@ 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 IsValidImageIndex(uint8_t image_index)
Helper to check whether an image index is valid for a particular vehicle.
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 WaterTileType::Clear water tile type).
Definition water_map.h:39
@ Canal
Canal.
Definition water_map.h:41
@ Sea
Sea.
Definition water_map.h:40
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:375
@ 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:3230
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:3322
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:3216
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3200
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