OpenTTD Source 20260731-master-g77ba2b244a
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#include "script/api/script_event_types.hpp"
39
40#include "table/strings.h"
41
42#include <unordered_set>
43
44#include "safeguards.h"
45
48
55{
56 if (HasTileWaterClass(tile)) return GetWaterClass(tile);
59 return WaterClass::Canal;
60 }
61 if (IsTileType(tile, TileType::Railway)) {
63 return WaterClass::Sea;
64 }
65 NOT_REACHED();
66}
67
68static const uint16_t _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
69
71template <>
72bool IsValidImageIndex<VehicleType::Ship>(uint8_t image_index)
73{
74 return image_index < lengthof(_ship_sprites);
75}
76
77static inline TrackBits GetTileShipTrackStatus(TileIndex tile)
78{
80}
81
82static void GetShipIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result)
83{
84 const Engine *e = Engine::Get(engine);
85 uint8_t spritenum = e->VehInfo<ShipVehicleInfo>().image_index;
86
87 if (IsCustomVehicleSpriteNum(spritenum)) {
88 GetCustomVehicleIcon(engine, Direction::W, image_type, result);
89 if (result->IsValid()) return;
90
91 spritenum = e->original_image_index;
92 }
93
94 assert(IsValidImageIndex<VehicleType::Ship>(spritenum));
95 result->Set(to_underlying(Direction::W) + _ship_sprites[spritenum]);
96}
97
98void DrawShipEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
99{
101 GetShipIcon(engine, image_type, &seq);
102
103 Rect rect;
104 seq.GetBounds(&rect);
105 preferred_x = Clamp(preferred_x,
106 left - UnScaleGUI(rect.left),
107 right - UnScaleGUI(rect.right));
108
109 seq.Draw(preferred_x, y, pal, pal == PALETTE_CRASH);
110}
111
121void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
122{
124 GetShipIcon(engine, image_type, &seq);
125
126 Rect rect;
127 seq.GetBounds(&rect);
128
129 width = UnScaleGUI(rect.Width());
130 height = UnScaleGUI(rect.Height());
131 xoffs = UnScaleGUI(rect.left);
132 yoffs = UnScaleGUI(rect.top);
133}
134
136{
137 uint8_t spritenum = this->spritenum;
138
139 if (image_type == EngineImageType::OnMap) direction = this->rotation;
140
141 if (IsCustomVehicleSpriteNum(spritenum)) {
142 GetCustomVehicleSprite(this, direction, image_type, result);
143 if (result->IsValid()) return;
144
146 }
147
149 result->Set(_ship_sprites[spritenum] + to_underlying(direction));
150}
151
152static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)
153{
154 const int max_region_distance = (max_distance / WATER_REGION_EDGE_LENGTH) + 1;
155
156 static std::unordered_set<int> visited_patch_hashes;
157 static std::deque<WaterRegionPatchDesc> patches_to_search;
158 visited_patch_hashes.clear();
159 patches_to_search.clear();
160
161 /* Step 1: find a set of reachable Water Region Patches using BFS. */
162 const WaterRegionPatchDesc start_patch = GetWaterRegionPatchInfo(v->tile);
163 patches_to_search.push_back(start_patch);
164 visited_patch_hashes.insert(CalculateWaterRegionPatchHash(start_patch));
165
166 while (!patches_to_search.empty()) {
167 /* Remove first patch from the queue and make it the current patch. */
168 const WaterRegionPatchDesc current_node = patches_to_search.front();
169 patches_to_search.pop_front();
170
171 /* Add neighbours of the current patch to the search queue. */
172 VisitWaterRegionPatchCallback visit_func = [&](const WaterRegionPatchDesc &water_region_patch) {
173 /* Note that we check the max distance per axis, not the total distance. */
174 if (std::abs(water_region_patch.x - start_patch.x) > max_region_distance ||
175 std::abs(water_region_patch.y - start_patch.y) > max_region_distance) return;
176
177 const int hash = CalculateWaterRegionPatchHash(water_region_patch);
178 if (visited_patch_hashes.count(hash) == 0) {
179 visited_patch_hashes.insert(hash);
180 patches_to_search.push_back(water_region_patch);
181 }
182 };
183
184 VisitWaterRegionPatchNeighbours(current_node, visit_func);
185 }
186
187 /* Step 2: Find the closest depot within the reachable Water Region Patches. */
188 const Depot *best_depot = nullptr;
189 uint best_dist_sq = std::numeric_limits<uint>::max();
190 for (const Depot *depot : Depot::Iterate()) {
191 const TileIndex tile = depot->xy;
192 if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) {
193 const uint dist_sq = DistanceSquare(tile, v->tile);
194 if (dist_sq < best_dist_sq && dist_sq <= max_distance * max_distance &&
195 visited_patch_hashes.count(CalculateWaterRegionPatchHash(GetWaterRegionPatchInfo(tile))) > 0) {
196 best_dist_sq = dist_sq;
197 best_depot = depot;
198 }
199 }
200 }
201
202 return best_depot;
203}
204
205static void CheckIfShipNeedsService(Vehicle *v)
206{
207 if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
208 if (v->IsChainInDepot()) {
210 return;
211 }
212
213 uint max_distance = _settings_game.pf.yapf.maximum_go_to_depot_penalty / YAPF_TILE_LENGTH;
214
215 const Depot *depot = FindClosestShipDepot(v, max_distance);
216
217 if (depot == nullptr) {
218 if (v->current_order.IsType(OT_GOTO_DEPOT)) {
220 SetWindowWidgetDirty(WindowClass::VehicleView, v->index, WID_VV_START_STOP);
221 }
222 return;
223 }
224
226 v->SetDestTile(depot->xy);
227 SetWindowWidgetDirty(WindowClass::VehicleView, v->index, WID_VV_START_STOP);
228}
229
234{
235 const ShipVehicleInfo *svi = ShipVehInfo(this->engine_type);
236
237 /* Get speed fraction for the current water type. Aqueducts are always canals. */
238 bool is_ocean = GetEffectiveWaterClass(this->tile) == WaterClass::Sea;
239 uint raw_speed = GetVehicleProperty(this, PROP_SHIP_SPEED, svi->max_speed);
240 this->vcache.cached_max_speed = svi->ApplyWaterClassSpeedFrac(raw_speed, is_ocean);
241
242 /* Update cargo aging period. */
243 this->vcache.cached_cargo_age_period = GetVehicleProperty(this, PROP_SHIP_CARGO_AGE_PERIOD, EngInfo(this->engine_type)->cargo_age_period);
244
245 this->UpdateVisualEffect();
246}
247
249{
250 const Engine *e = this->GetEngine();
251 uint cost_factor = GetVehicleProperty(this, PROP_SHIP_RUNNING_COST_FACTOR, e->VehInfo<ShipVehicleInfo>().running_cost);
252 return GetPrice(Price::RunningShip, cost_factor, e->GetGRF());
253}
254
257{
258 AgeVehicle(this);
259}
260
263{
264 EconomyAgeVehicle(this);
265
266 if ((++this->day_counter & 7) == 0) {
268 }
269
271 CheckIfShipNeedsService(this);
272
273 CheckOrders(this);
274
275 if (this->running_ticks == 0) return;
276
278
279 this->profit_this_year -= cost.GetCost();
280 this->running_ticks = 0;
281
283
284 SetWindowDirty(WindowClass::VehicleDetails, this->index);
285 /* we need this for the profit */
286 SetWindowClassesDirty(WindowClass::ShipList);
287}
288
290{
291 if (this->vehstatus.Test(VehState::Crashed)) return Trackdir::Invalid;
292
293 if (this->IsInDepot()) {
294 /* We'll assume the ship is facing outwards */
296 }
297
298 if (this->state == Track::Wormhole) {
299 /* ship on aqueduct, so just use its direction and assume a diagonal track */
301 }
302
304}
305
307{
308 this->colourmap = PAL_NONE;
309 this->UpdateViewport(true, false);
310 this->UpdateCache();
311}
312
313void Ship::PlayLeaveStationSound(bool force) const
314{
315 if (PlayVehicleSound(this, VSE_START, force)) return;
316 SndPlayVehicleFx(ShipVehInfo(this->engine_type)->sfx, this);
317}
318
320{
321 if (station == this->last_station_visited) this->last_station_visited = StationID::Invalid();
322
323 const Station *st = Station::Get(station);
324 if (CanVehicleUseStation(this, st)) {
325 return st->xy;
326 } else {
328 return TileIndex{};
329 }
330}
331
333{
334 static constexpr DirectionIndexArray<SpriteBounds> ship_bounds{{{
335 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // N
336 {{-16, -3, 0}, {32, 6, 6}, {}}, // NE
337 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // E
338 {{ -3, -16, 0}, { 6, 32, 6}, {}}, // SE
339 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // S
340 {{-16, -3, 0}, {32, 6, 6}, {}}, // SW
341 {{ -3, -3, 0}, { 6, 6, 6}, {}}, // W
342 {{ -3, -16, 0}, { 6, 32, 6}, {}}, // NW
343 }}};
344
345 this->bounds = ship_bounds[this->rotation];
346
347 if (this->direction != this->rotation) {
348 /* If we are rotating, then it is possible the ship was moved to its next position. In that
349 * case, because we are still showing the old direction, the ship will appear to glitch sideways
350 * slightly. We can work around this by applying an additional offset to make the ship appear
351 * where it was before it moved. */
352 this->bounds.origin.x -= this->x_pos - this->rotation_x_pos;
353 this->bounds.origin.y -= this->y_pos - this->rotation_y_pos;
354 }
355}
356
357static bool CheckReverseShip(const Ship *v, Trackdir *trackdir = nullptr)
358{
359 /* Ask pathfinder for best direction */
360 return YapfShipCheckReverse(v, trackdir);
361}
362
369{
370 if (!v->IsChainInDepot()) return false;
371
372 /* Check if we should wait here for unbunching. */
373 if (v->IsWaitingForUnbunching()) return true;
374
375 /* We are leaving a depot, but have to go to the exact same one; re-enter */
376 if (v->current_order.IsType(OT_GOTO_DEPOT) &&
379 return true;
380 }
381
382 /* Don't leave depot if no destination set */
383 if (v->dest_tile == INVALID_TILE) return true;
384
385 /* Don't leave depot if another vehicle is already entering/leaving */
386 /* This helps avoid CPU load if many ships are set to start at the same time */
387 if (HasVehicleOnTile(v->tile, [](const Vehicle *u) {
388 return u->type == VehicleType::Ship && u->cur_speed != 0;
389 })) return true;
390
393 if (CheckReverseShip(v)) v->direction = ReverseDir(v->direction);
394
396 v->rotation = v->direction;
398 v->cur_speed = 0;
399 v->UpdateViewport(true, true);
400 SetWindowDirty(WindowClass::VehicleDepot, v->tile);
401
405 InvalidateWindowData(WindowClass::VehicleDepot, v->tile);
406 SetWindowClassesDirty(WindowClass::ShipList);
407
408 return false;
409}
410
416static uint ShipAccelerate(Vehicle *v)
417{
418 uint speed;
419 speed = std::min<uint>(v->cur_speed + v->acceleration, v->vcache.cached_max_speed);
420 speed = std::min<uint>(speed, v->current_order.GetMaxSpeed() * 2);
421
422 /* updates statusbar only if speed have changed to save CPU time */
423 if (speed != v->cur_speed) {
424 v->cur_speed = speed;
425 SetWindowWidgetDirty(WindowClass::VehicleView, v->index, WID_VV_START_STOP);
426 }
427
428 const uint advance_speed = v->GetAdvanceSpeed(speed);
429 const uint number_of_steps = (advance_speed + v->progress) / v->GetAdvanceDistance();
430 const uint remainder = (advance_speed + v->progress) % v->GetAdvanceDistance();
431 assert(remainder <= std::numeric_limits<uint8_t>::max());
432 v->progress = static_cast<uint8_t>(remainder);
433 return number_of_steps;
434}
435
441static void ShipArrivesAt(const Vehicle *v, Station *st)
442{
443 /* Check if station was ever visited before */
444 if (!st->had_vehicle_of_type.Test(StationVehicleType::Ship)) {
445 st->had_vehicle_of_type.Set(StationVehicleType::Ship);
446
448 GetEncodedString(STR_NEWS_FIRST_SHIP_ARRIVAL, st->index),
450 v->index,
451 st->index
452 );
453 AI::NewEvent(v->owner, new ScriptEventStationFirstVehicle(st->index, v->index));
454 Game::NewEvent(new ScriptEventStationFirstVehicle(st->index, v->index));
455 }
456}
457
458
468{
469 bool path_found = true;
470 Track track;
471
472 if (v->dest_tile == INVALID_TILE) {
473 /* No destination, don't invoke pathfinder. */
474 track = TrackBitsToTrack(v->state);
475 if (!IsDiagonalTrack(track)) track = TrackToOppositeTrack(track);
476 if (!tracks.Test(track)) track = FindFirstTrack(tracks);
477 path_found = false;
478 } else {
479 /* Attempt to follow cached path. */
480 if (!v->path.empty()) {
481 track = TrackdirToTrack(v->path.back().trackdir);
482
483 if (tracks.Test(track)) {
484 v->path.pop_back();
485 /* HandlePathfindResult() is not called here because this is not a new pathfinder result. */
486 return track;
487 }
488
489 /* Cached path is invalid so continue with pathfinder. */
490 v->path.clear();
491 }
492
493 track = YapfShipChooseTrack(v, tile, path_found, v->path);
494 }
495
496 v->HandlePathfindingResult(path_found);
497 return track;
498}
499
507{
508 TrackBits tracks = GetTileShipTrackStatus(tile) & DiagdirReachesTracks(dir);
509
510 return tracks;
511}
512
518static int ShipTestUpDownOnLock(const Ship *v)
519{
520 /* Suitable tile? */
521 if (!IsTileType(v->tile, TileType::Water) || !IsLock(v->tile) || GetLockPart(v->tile) != LockPart::Middle) return 0;
522
523 /* Must be at the centre of the lock */
524 if ((v->x_pos & 0xF) != 8 || (v->y_pos & 0xF) != 8) return 0;
525
527 assert(IsValidDiagDirection(diagdir));
528
529 if (DirToDiagDir(v->direction) == diagdir) {
530 /* Move up */
531 return (v->z_pos < GetTileMaxZ(v->tile) * (int)TILE_HEIGHT) ? 1 : 0;
532 } else {
533 /* Move down */
534 return (v->z_pos > GetTileZ(v->tile) * (int)TILE_HEIGHT) ? -1 : 0;
535 }
536}
537
544{
545 /* Moving up/down through lock */
546 int dz = ShipTestUpDownOnLock(v);
547 if (dz == 0) return false;
548
549 if (v->cur_speed != 0) {
550 v->cur_speed = 0;
551 SetWindowWidgetDirty(WindowClass::VehicleView, v->index, WID_VV_START_STOP);
552 }
553
554 if ((v->tick_counter & 7) == 0) {
555 v->z_pos += dz;
556 v->UpdatePosition();
557 v->UpdateViewport(true, true);
558 }
559
560 return true;
561}
562
569bool IsShipDestinationTile(TileIndex tile, StationID station)
570{
571 assert(IsDockingTile(tile));
572 /* Check each tile adjacent to docking tile. */
574 TileIndex t = tile + TileOffsByDiagDir(d);
575 if (!IsValidTile(t)) continue;
576 if (IsDockTile(t) && GetStationIndex(t) == station && IsDockWaterPart(t)) return true;
578 const Industry *i = Industry::GetByTile(t);
579 if (i->neutral_station != nullptr && i->neutral_station->index == station) return true;
580 }
581 if (IsTileType(t, TileType::Station) && IsOilRig(t) && GetStationIndex(t) == station) return true;
582 }
583 return false;
584}
585
586static void ReverseShipIntoTrackdir(Ship *v, Trackdir trackdir)
587{
588 static constexpr TrackdirIndexArray<Direction> _trackdir_to_direction{
591 };
592
593 v->direction = _trackdir_to_direction[trackdir];
594 assert(v->direction != Direction::Invalid);
596
597 /* Remember our current location to avoid movement glitch */
598 v->rotation_x_pos = v->x_pos;
599 v->rotation_y_pos = v->y_pos;
600 v->cur_speed = 0;
601 v->path.clear();
602
603 v->UpdatePosition();
604 v->UpdateViewport(true, true);
605}
606
607static void ReverseShip(Ship *v)
608{
610
611 /* Remember our current location to avoid movement glitch */
612 v->rotation_x_pos = v->x_pos;
613 v->rotation_y_pos = v->y_pos;
614 v->cur_speed = 0;
615 v->path.clear();
616
617 v->UpdatePosition();
618 v->UpdateViewport(true, true);
619}
620
621static void ShipController(Ship *v)
622{
623 v->tick_counter++;
625
626 if (v->HandleBreakdown()) return;
627
628 if (v->vehstatus.Test(VehState::Stopped)) return;
629
630 if (ProcessOrders(v) && CheckReverseShip(v)) return ReverseShip(v);
631
632 v->HandleLoading();
633
634 if (v->current_order.IsType(OT_LOADING)) return;
635
636 if (CheckShipStayInDepot(v)) return;
637
638 v->ShowVisualEffect();
639
640 /* Rotating on spot */
641 if (v->direction != v->rotation) {
642 if ((v->tick_counter & 7) == 0) {
644 v->rotation = ChangeDir(v->rotation, LimitDirDiff(diff));
645 /* Invalidate the sprite cache direction to force recalculation of viewport */
647 v->UpdateViewport(true, true);
648 }
649 return;
650 }
651
652 if (ShipMoveUpDownOnLock(v)) return;
653
654 const uint number_of_steps = ShipAccelerate(v);
655 for (uint i = 0; i < number_of_steps; ++i) {
656 if (ShipMoveUpDownOnLock(v)) return;
657
659 if (v->state != Track::Wormhole) {
660 /* Not on a bridge */
661 if (gp.old_tile == gp.new_tile) {
662 /* Staying in tile */
663 if (v->IsInDepot()) {
664 gp.x = v->x_pos;
665 gp.y = v->y_pos;
666 } else {
667 /* Not inside depot */
668 auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
669 if (vets.Test(VehicleEnterTileState::CannotEnter)) return ReverseShip(v);
670
671 /* A leave station order only needs one tick to get processed, so we can
672 * always skip ahead. */
673 if (v->current_order.IsType(OT_LEAVESTATION)) {
674 v->current_order.Free();
675 SetWindowWidgetDirty(WindowClass::VehicleView, v->index, WID_VV_START_STOP);
676 /* Test if continuing forward would lead to a dead-end, moving into the dock. */
677 const DiagDirection exitdir = VehicleExitDir(v->direction, v->state);
678 const TileIndex tile = TileAddByDiagDir(v->tile, exitdir);
679 if (TrackdirBitsToTrackBits(GetTileTrackStatus(tile, TransportType::Water, RoadTramType::Invalid, exitdir).trackdirs).None()) return ReverseShip(v);
680 } else if (v->dest_tile != INVALID_TILE) {
681 /* We have a target, let's see if we reached it... */
682 if (v->current_order.IsType(OT_GOTO_WAYPOINT) &&
683 DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
684 /* We got within 3 tiles of our target buoy, so let's skip to our
685 * next order */
686 UpdateVehicleTimetable(v, true);
689 } else if (v->current_order.IsType(OT_GOTO_DEPOT) &&
690 v->dest_tile == gp.new_tile) {
691 /* Depot orders really need to reach the tile */
692 if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) {
694 return;
695 }
696 } else if (v->current_order.IsType(OT_GOTO_STATION) && IsDockingTile(gp.new_tile)) {
697 /* Process station in the orderlist. */
698 Station *st = Station::Get(v->current_order.GetDestination().ToStationID());
699 if (st->docking_station.Contains(gp.new_tile) && IsShipDestinationTile(gp.new_tile, st->index)) {
700 v->last_station_visited = st->index;
701 if (st->facilities.Test(StationFacility::Dock)) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
702 ShipArrivesAt(v, st);
703 v->BeginLoading();
704 } else { // leave stations without docks right away
707 }
708 }
709 }
710 }
711 }
712 } else {
713 /* New tile */
714 if (!IsValidTile(gp.new_tile)) return ReverseShip(v);
715
716 const DiagDirection diagdir = DiagdirBetweenTiles(gp.old_tile, gp.new_tile);
717 assert(diagdir != DiagDirection::Invalid);
718 const TrackBits tracks = GetAvailShipTracks(gp.new_tile, diagdir);
719 if (tracks.None()) {
720 Trackdir trackdir = Trackdir::Invalid;
721 CheckReverseShip(v, &trackdir);
722 if (trackdir == Trackdir::Invalid) return ReverseShip(v);
723 return ReverseShipIntoTrackdir(v, trackdir);
724 }
725
726 /* Choose a direction, and continue if we find one */
727 const Track track = ChooseShipTrack(v, gp.new_tile, tracks);
728 if (!IsValidTrack(track)) return ReverseShip(v);
729
730 /* Update XY to reflect the entrance to the new tile, and select the direction to use */
731 Direction chosen_dir = VehicleEnterTileCoordinates(gp, diagdir, track);
732
733 /* Call the landscape function and tell it that the vehicle entered the tile */
734 auto vets = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
735 if (vets.Test(VehicleEnterTileState::CannotEnter)) return ReverseShip(v);
736
738 v->tile = gp.new_tile;
739 v->state = track;
740
741 /* Update ship cache when the water class changes. Aqueducts are always canals. */
743 }
744
745 const Direction new_direction = chosen_dir;
746 const DirDiff diff = DirDifference(new_direction, v->direction);
747 switch (diff) {
748 case DirDiff::Same:
749 case DirDiff::Right45:
750 case DirDiff::Left45:
751 /* Continue at speed */
752 v->rotation = v->direction = new_direction;
753 break;
754
755 default:
756 /* Stop for rotation */
757 v->cur_speed = 0;
758 v->direction = new_direction;
759 /* Remember our current location to avoid movement glitch */
760 v->rotation_x_pos = v->x_pos;
761 v->rotation_y_pos = v->y_pos;
762 break;
763 }
764 }
765 } else {
766 /* On a bridge */
768 v->x_pos = gp.x;
769 v->y_pos = gp.y;
770 v->UpdatePosition();
771 if (!v->vehstatus.Test(VehState::Hidden)) v->Vehicle::UpdateViewport(true);
772 continue;
773 }
774
775 /* Ship is back on the bridge head, we need to consume its path
776 * cache entry here as we didn't have to choose a ship track. */
777 if (!v->path.empty()) v->path.pop_back();
778 }
779
780 /* update image of ship, as well as delta XY */
781 v->x_pos = gp.x;
782 v->y_pos = gp.y;
783
784 v->UpdatePosition();
785 v->UpdateViewport(true, true);
786 }
787}
788
790{
792
793 if (!this->vehstatus.Test(VehState::Stopped)) this->running_ticks++;
794
795 ShipController(this);
796
797 return true;
798}
799
801{
802 if (tile == this->dest_tile) return;
803 this->path.clear();
804 this->dest_tile = tile;
805}
806
816{
817 tile = GetShipDepotNorthTile(tile);
818 if (flags.Test(DoCommandFlag::Execute)) {
819 int x;
820 int y;
821
822 const ShipVehicleInfo *svi = &e->VehInfo<ShipVehicleInfo>();
823
824 Ship *v = Ship::Create();
825 *ret = v;
826
828 v->tile = tile;
829 x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
830 y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
831 v->x_pos = x;
832 v->y_pos = y;
833 v->z_pos = GetSlopePixelZ(x, y);
834
835 v->direction = DiagDirToDir(GetShipDepotDirection(tile));
836
837 /* UpdateDeltaXY() requires rotation to be initialised as well. */
838 v->rotation = v->direction;
839 v->UpdateDeltaXY();
840
842
843 v->spritenum = svi->image_index;
844 v->cargo_type = e->GetDefaultCargoType();
845 assert(IsValidCargoType(v->cargo_type));
846 v->cargo_cap = svi->capacity;
847 v->refit_cap = 0;
848
849 v->last_station_visited = StationID::Invalid();
850 v->last_loading_station = StationID::Invalid();
851 v->engine_type = e->index;
852
853 v->reliability = e->reliability;
854 v->reliability_spd_dec = e->reliability_spd_dec;
855 v->max_age = e->GetLifeLengthInDays();
856
857 v->state = Track::Depot;
858
859 v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
860 v->date_of_last_service = TimerGameEconomy::date;
861 v->date_of_last_service_newgrf = TimerGameCalendar::date;
862 v->build_year = TimerGameCalendar::year;
863 v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY);
864 v->random_bits = Random();
865
866 v->acceleration = svi->acceleration;
867 v->UpdateCache();
868
870 v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent);
871
872 v->InvalidateNewGRFCacheOfChain();
873
874 v->cargo_cap = e->DetermineCapacity(v);
875
876 v->InvalidateNewGRFCacheOfChain();
877
878 v->UpdatePosition();
879 }
880
881 return CommandCost();
882}
883
885{
886 const Depot *depot = FindClosestShipDepot(this, MAX_SHIP_DEPOT_SEARCH_DISTANCE);
887 if (depot == nullptr) return ClosestDepot();
888
889 return ClosestDepot(depot->xy, depot->index);
890}
Base functions for all AIs.
@ None
Tile is not animated.
@ BuiltAsPrototype
Vehicle is a prototype (accepted as exclusive preview).
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:110
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition ai_core.cpp:231
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr bool None() const
Test if none of the values are set.
constexpr Timpl & Reset()
Reset all bits.
constexpr Timpl & Set()
Set 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:52
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:227
EngineFlags flags
Flags of the engine.
Definition engine_base.h:59
uint8_t original_image_index
Original vehicle image index, thus the image index of the overridden vehicle.
Definition engine_base.h:63
TimerGameCalendar::Date GetLifeLengthInDays() const
Returns the vehicle's (not model's!) life length in days.
Definition engine.cpp:469
CargoType GetDefaultCargoType() const
Determines the default cargo type of an engine.
Definition engine_base.h:96
uint16_t reliability
Current reliability of the engine.
Definition engine_base.h:51
Iterate a range of enum values.
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
EnumBitSet< DoCommandFlag, uint16_t > DoCommandFlags
Bitset of DoCommandFlag elements.
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.
DirDiff LimitDirDiff(DirDiff d)
Limit a direction difference to up to 45 degrees.
DiagDirection DirToDiagDir(Direction dir)
Convert a Direction to a DiagDirection.
DirDiff
Enumeration for the difference between two directions.
@ Left45
Angle of 45 degrees left.
@ Same
Both directions faces to the same direction.
@ Right45
Angle of 45 degrees right.
Direction
Defines the 8 directions on the map.
@ Invalid
Flag for an invalid direction.
@ SW
Southwest.
@ NW
Northwest.
@ NE
Northeast.
@ SE
Southeast.
EnumIndexArray< T, Direction, Direction::End > DirectionIndexArray
Array with Direction as index.
DiagDirection
Enumeration for diagonal directions.
@ Invalid
Flag for an invalid DiagDirection.
@ End
Used for iterations.
Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift)
Determine a certain price.
Definition economy.cpp:937
@ ShipRun
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.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
fluid_settings_t * settings
FluidSynth settings handle.
Types for recording game performance data.
@ GameLoopShips
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:109
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:601
@ HalfTileWater
Grass with a fence and shore or water on the free halftile.
Definition rail_map.h:582
@ Invalid
Invalid marker.
Definition road_type.h:42
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:569
WaterClass GetEffectiveWaterClass(TileIndex tile)
Determine the effective WaterClass for a ship travelling on a tile.
Definition ship_cmd.cpp:54
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:47
CommandCost CmdBuildShip(DoCommandFlags flags, TileIndex tile, const Engine *e, Vehicle **ret)
Build a ship.
Definition ship_cmd.cpp:815
static uint ShipAccelerate(Vehicle *v)
Accelerates the ship towards its target speed.
Definition ship_cmd.cpp:416
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:506
static bool ShipMoveUpDownOnLock(Ship *v)
Test and move a ship up or down in a lock.
Definition ship_cmd.cpp:543
bool IsShipDestinationTile(TileIndex tile, StationID station)
Test if a tile is a docking tile for the given station.
Definition ship_cmd.cpp:569
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:121
static void ShipArrivesAt(const Vehicle *v, Station *st)
Ship arrives at a dock.
Definition ship_cmd.cpp:441
WaterClass GetEffectiveWaterClass(TileIndex tile)
Determine the effective WaterClass for a ship travelling on a tile.
Definition ship_cmd.cpp:54
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:518
static bool CheckShipStayInDepot(Ship *v)
Checks whether a ship should stay in the depot.
Definition ship_cmd.cpp:368
static Track ChooseShipTrack(Ship *v, TileIndex tile, TrackBits tracks)
Runs the pathfinder to choose a track to continue along.
Definition ship_cmd.cpp:467
bool IsValidImageIndex< VehicleType::Ship >(uint8_t image_index)
Helper to check whether an image index is valid for a particular vehicle.
Definition ship_cmd.cpp:72
Command definitions related to ships.
DiagDirection GetInclinedSlopeDirection(Slope s)
Returns the direction of an inclined slope.
Definition slope_func.h:249
Functions related to sound.
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition sprites.h:1793
static const SpriteID SPR_IMG_QUERY
Definition sprites.h:1274
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.
@ Dock
Station with a dock.
@ Ship
Station has seen a ship.
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:261
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:64
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:253
Station * neutral_station
Associated neutral station.
Definition industry.h:110
Direction last_direction
Last direction we obtained sprites for.
uint16_t GetMaxSpeed() const
Get the maximum 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:48
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:74
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 T * Create(Targs &&... args)
static Engine * Get(auto index)
int Width() const
Get width of Rect.
int Height() const
Get height of Rect.
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:789
Money GetRunningCost() const override
Gets the running cost of a vehicle.
Definition ship_cmd.cpp:248
TileIndex GetOrderStationLocation(StationID station) override
Determine the location for the station where the vehicle goes to next.
Definition ship_cmd.cpp:319
void SetDestTile(TileIndex tile) override
Set the destination of this vehicle.
Definition ship_cmd.cpp:800
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:332
void OnNewCalendarDay() override
Calendar day handler.
Definition ship_cmd.cpp:256
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:884
void MarkDirty() override
Marks the vehicles to be redrawn and updates cached variables.
Definition ship_cmd.cpp:306
Trackdir GetVehicleTrackdir() const override
Returns the Trackdir on which the vehicle is currently located.
Definition ship_cmd.cpp:289
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:313
void OnNewEconomyDay() override
Economy day handler.
Definition ship_cmd.cpp:262
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override
Gets the sprite to show for the given direction.
Definition ship_cmd.cpp:135
void UpdateCache()
Update the caches of this ship.
Definition ship_cmd.cpp:233
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:124
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:152
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:749
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:2453
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:2681
void LeaveUnbunchingDepot()
Leave an unbunching depot and calculate the next departure time for shared order vehicles.
Definition vehicle.cpp:2533
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:793
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:2228
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:2580
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:1375
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:1700
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:2834
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:293
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:1864
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:235
Track TrackToOppositeTrack(Track t)
Find the opposite track to a given track.
Definition track_func.h:204
bool IsDiagonalTrack(Track track)
Checks if a given Track is diagonal.
Definition track_func.h:514
DiagDirection VehicleExitDir(Direction direction, TrackBits track)
Determine the side in which the vehicle will leave the tile.
Definition track_func.h:609
Track TrackBitsToTrack(TrackBits tracks)
Converts TrackBits to Track.
Definition track_func.h:166
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:405
bool IsValidTrack(Track track)
Checks if a Track is valid.
Definition track_func.h:24
Track FindFirstTrack(TrackBits tracks)
Returns first Track from TrackBits or Track::Invalid.
Definition track_func.h:150
TrackBits DiagdirReachesTracks(DiagDirection diagdir)
Returns all tracks that can be reached when entering a tile from a given (diagonal) direction.
Definition track_func.h:468
Trackdir DiagDirToDiagTrackdir(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal trackdir that runs in that direction.
Definition track_func.h:432
TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
Maps a Trackdir to the corresponding TrackdirBits value.
Definition track_func.h:86
Track AxisToTrack(Axis a)
Convert an Axis to the corresponding Track Axis::X -> Track::X Axis::Y -> Track::Y Uses the fact that...
Definition track_func.h:62
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
Definition track_func.h:343
TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
Discards all directional information from a TrackdirBits value.
Definition track_func.h:281
EnumBitSet< Track, uint8_t > TrackBits
Bitset of Track elements.
Definition track_type.h:43
Trackdir
Enumeration for tracks and directions.
Definition track_type.h:63
@ X_NE
X-axis and direction to north-east.
Definition track_type.h:64
@ Invalid
Flag for an invalid trackdir.
Definition track_type.h:82
@ Y_NW
Y-axis and direction to north-west.
Definition track_type.h:73
EnumIndexArray< T, Trackdir, Trackdir::End > TrackdirIndexArray
Array with Trackdir as index.
Definition track_type.h:90
Track
These are used to specify a single track.
Definition track_type.h:19
@ Depot
Special flag indicating a vehicle is inside a depot.
Definition track_type.h:30
@ Wormhole
Special flag indicating vehicle is inside a bridge or tunnel.
Definition track_type.h:29
@ 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:1563
void VehicleServiceInDepot(Vehicle *v)
Service a vehicle and all subsequent vehicles in the consist.
Definition vehicle.cpp:188
void CheckVehicleBreakdown(Vehicle *v)
Periodic check for a vehicle to maybe break down.
Definition vehicle.cpp:1319
GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
Get position information of a vehicle when moving one pixel in the direction it is facing.
Definition vehicle.cpp:1803
void DecreaseVehicleValue(Vehicle *v)
Decrease the value of a vehicle.
Definition vehicle.cpp:1298
void EconomyAgeVehicle(Vehicle *v)
Update economy age of a vehicle.
Definition vehicle.cpp:1441
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition vehicle.cpp:3112
void AgeVehicle(Vehicle *v)
Update age of a vehicle.
Definition vehicle.cpp:1453
Direction VehicleEnterTileCoordinates(GetNewVehiclePosResult &gp, DiagDirection enterdir, Track track)
Lookup new subposition coordinates and direction to use when entering a new tile, applying the subcoo...
Definition vehicle.cpp:3399
@ 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.
@ OnMap
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:3226
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:3318
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:3212
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3196
Window functions not directly related to making/drawing windows.
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