Files @ r25958:603d75b53498
Branch filter:

Location: cpp/openttd-patchpack/source/src/roadveh.h - annotation

Patric Stout
Doc: update multiplayer documentation with latest changes (#9552)

Although several places were fixed during the PR making the change,
not all made it in this document.

While at it, removed all kinds of Markdown warnings by an excessive
usage of spacebar in this document.
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r6417:89329fa8ac80
r6393:f9322fdf4c2c
r5475:3f5cd13d1b63
r5475:3f5cd13d1b63
r5475:3f5cd13d1b63
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r15934:789c54d0000d
r23698:1872cc5b7dd7
r23698:1872cc5b7dd7
r16337:318cee923059
r23423:b49906a7682e
r5475:3f5cd13d1b63
r11978:b70e888fac6f
r11978:b70e888fac6f
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r16527:9475ed282143
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r17194:734289f58f1f
r17194:734289f58f1f
r11979:a450390d0f16
r18737:1ee35da7fa2f
r11979:a450390d0f16
r11979:a450390d0f16
r11034:b133414fb70f
r15173:a59afd6301a6
r15173:a59afd6301a6
r11034:b133414fb70f
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r15173:a59afd6301a6
r11034:b133414fb70f
r17196:ef67da674066
r17196:ef67da674066
r17196:ef67da674066
r18266:8aae3fd9e028
r19884:a1593074c6b8
r8890:02179c54681e
r23423:b49906a7682e
r23670:17ce345f83e6
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r23423:b49906a7682e
r6552:7cade7798fcb
r12033:6a560c929ec8
r6552:7cade7798fcb
r18730:83ef302fe140
r23423:b49906a7682e
r11979:a450390d0f16
r11979:a450390d0f16
r11979:a450390d0f16
r17194:734289f58f1f
r17194:734289f58f1f
r17226:04f59d7fdf18
r11979:a450390d0f16
r11979:a450390d0f16
r23698:1872cc5b7dd7
r23698:1872cc5b7dd7
r11979:a450390d0f16
r12090:c20f83257241
r17128:d4dca9b2b250
r6552:7cade7798fcb
r7412:e5f07529a093
r6552:7cade7798fcb
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r6553:04028e73a0f7
r22868:6eb08946de7f
r6563:67c636a8e3d4
r17113:503067d0eb7e
r22459:c1921e75ce89
r17163:be3746722ab5
r16373:fab42163de3d
r13482:56711f143646
r23607:36c15679007d
r19464:9f131ef157fd
r11965:2b94ac4aa35a
r8467:0ea88f22d4aa
r13863:252b1a5c4f87
r11971:ac7eb21a00e4
r8827:6ee5217ef94b
r8890:02179c54681e
r12294:7f9f5ab6fe85
r13842:5f8f28d5f86b
r13842:5f8f28d5f86b
r14747:a465914ccbff
r17166:c2f53ab3046a
r23423:b49906a7682e
r14747:a465914ccbff
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r16337:318cee923059
r16337:318cee923059
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r20188:c7660e0c9b5b
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r16337:318cee923059
r16337:318cee923059
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r16337:318cee923059
r16337:318cee923059
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r15770:9575f66010a4
r15625:2ee9e0168398
r16380:aa3ab792f276
r15625:2ee9e0168398
r18782:6453522c2154
r15625:2ee9e0168398
r16380:aa3ab792f276
r15625:2ee9e0168398
r15625:2ee9e0168398
r14745:06b1ec7617d7
r15628:ca75f7a370e8
r15628:ca75f7a370e8
r15628:ca75f7a370e8
r18782:6453522c2154
r15628:ca75f7a370e8
r15628:ca75f7a370e8
r15628:ca75f7a370e8
r15628:ca75f7a370e8
r15628:ca75f7a370e8
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r16380:aa3ab792f276
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r16380:aa3ab792f276
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r16380:aa3ab792f276
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r16380:aa3ab792f276
r16380:aa3ab792f276
r23698:1872cc5b7dd7
r16380:aa3ab792f276
r16380:aa3ab792f276
r16380:aa3ab792f276
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r16380:aa3ab792f276
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r23698:1872cc5b7dd7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r14745:06b1ec7617d7
r18782:6453522c2154
r14745:06b1ec7617d7
r23698:1872cc5b7dd7
r14746:8e3f2ad7663e
r14746:8e3f2ad7663e
r14746:8e3f2ad7663e
r14745:06b1ec7617d7
r17135:4ba298586dc1
r17135:4ba298586dc1
r18245:fb370bf5a3c0
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r18782:6453522c2154
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r17135:4ba298586dc1
r6552:7cade7798fcb
r6552:7cade7798fcb
r5475:3f5cd13d1b63
/*
 * This file is part of OpenTTD.
 * 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.
 * 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.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file src/roadveh.h Road vehicle states */

#ifndef ROADVEH_H
#define ROADVEH_H

#include "ground_vehicle.hpp"
#include "engine_base.h"
#include "cargotype.h"
#include "track_func.h"
#include "road.h"
#include "road_map.h"
#include "newgrf_engine.h"
#include <deque>

struct RoadVehicle;

/** Road vehicle states */
enum RoadVehicleStates {
	/*
	 * Lower 4 bits are used for vehicle track direction. (Trackdirs)
	 * When in a road stop (bit 5 or bit 6 set) these bits give the
	 * track direction of the entry to the road stop.
	 * As the entry direction will always be a diagonal
	 * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3
	 * are needed to hold this direction. Bit 1 is then used to show
	 * that the vehicle is using the second road stop bay.
	 * Bit 2 is then used for drive-through stops to show the vehicle
	 * is stopping at this road stop.
	 */

	/* Numeric values */
	RVSB_IN_DEPOT                = 0xFE,                      ///< The vehicle is in a depot
	RVSB_WORMHOLE                = 0xFF,                      ///< The vehicle is in a tunnel and/or bridge

	/* Bit numbers */
	RVS_USING_SECOND_BAY         =    1,                      ///< Only used while in a road stop
	RVS_ENTERED_STOP             =    2,                      ///< Only set when a vehicle has entered the stop
	RVS_DRIVE_SIDE               =    4,                      ///< Only used when retrieving move data
	RVS_IN_ROAD_STOP             =    5,                      ///< The vehicle is in a road stop
	RVS_IN_DT_ROAD_STOP          =    6,                      ///< The vehicle is in a drive-through road stop

	/* Bit sets of the above specified bits */
	RVSB_IN_ROAD_STOP            = 1 << RVS_IN_ROAD_STOP,     ///< The vehicle is in a road stop
	RVSB_IN_ROAD_STOP_END        = RVSB_IN_ROAD_STOP + TRACKDIR_END,
	RVSB_IN_DT_ROAD_STOP         = 1 << RVS_IN_DT_ROAD_STOP,  ///< The vehicle is in a drive-through road stop
	RVSB_IN_DT_ROAD_STOP_END     = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END,

	RVSB_DRIVE_SIDE              = 1 << RVS_DRIVE_SIDE,       ///< The vehicle is at the opposite side of the road

	RVSB_TRACKDIR_MASK           = 0x0F,                      ///< The mask used to extract track dirs
	RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09,                      ///< Only bits 0 and 3 are used to encode the trackdir for road stops
};

/** State information about the Road Vehicle controller */
static const uint RDE_NEXT_TILE = 0x80; ///< We should enter the next tile
static const uint RDE_TURNED    = 0x40; ///< We just finished turning

/* Start frames for when a vehicle enters a tile/changes its state.
 * The start frame is different for vehicles that turned around or
 * are leaving the depot as the do not start at the edge of the tile.
 * For trams there are a few different start frames as there are two
 * places where trams can turn. */
static const uint RVC_DEFAULT_START_FRAME                =  0;
static const uint RVC_TURN_AROUND_START_FRAME            =  1;
static const uint RVC_DEPOT_START_FRAME                  =  6;
static const uint RVC_START_FRAME_AFTER_LONG_TRAM        = 21;
static const uint RVC_TURN_AROUND_START_FRAME_SHORT_TRAM = 16;
/* Stop frame for a vehicle in a drive-through stop */
static const uint RVC_DRIVE_THROUGH_STOP_FRAME           = 11;
static const uint RVC_DEPOT_STOP_FRAME                   = 11;

/** The number of ticks a vehicle has for overtaking. */
static const byte RV_OVERTAKE_TIMEOUT = 35;

void RoadVehUpdateCache(RoadVehicle *v, bool same_length = false);
void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type);

struct RoadVehPathCache {
	std::deque<Trackdir> td;
	std::deque<TileIndex> tile;

	inline bool empty() const { return this->td.empty(); }

	inline size_t size() const
	{
		assert(this->td.size() == this->tile.size());
		return this->td.size();
	}

	inline void clear()
	{
		this->td.clear();
		this->tile.clear();
	}
};

/**
 * Buses, trucks and trams belong to this class.
 */
struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
	RoadVehPathCache path;  ///< Cached path.
	byte state;             ///< @see RoadVehicleStates
	byte frame;
	uint16 blocked_ctr;
	byte overtaking;        ///< Set to #RVSB_DRIVE_SIDE when overtaking, otherwise 0.
	byte overtaking_ctr;    ///< The length of the current overtake attempt.
	uint16 crashed_ctr;     ///< Animation counter when the vehicle has crashed. @see RoadVehIsCrashed
	byte reverse_ctr;

	RoadType roadtype;              //!< Roadtype of this vehicle.
	RoadTypes compatible_roadtypes; //!< Roadtypes this consist is powered on.

	/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
	RoadVehicle() : GroundVehicleBase() {}
	/** We want to 'destruct' the right class. */
	virtual ~RoadVehicle() { this->PreDestructor(); }

	friend struct GroundVehicle<RoadVehicle, VEH_ROAD>; // GroundVehicle needs to use the acceleration functions defined at RoadVehicle.

	void MarkDirty();
	void UpdateDeltaXY();
	ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_INC : EXPENSES_ROADVEH_RUN; }
	bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
	void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
	int GetDisplaySpeed() const { return this->gcache.last_speed / 2; }
	int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
	Money GetRunningCost() const;
	int GetDisplayImageWidth(Point *offset = nullptr) const;
	bool IsInDepot() const { return this->state == RVSB_IN_DEPOT; }
	bool Tick();
	void OnNewDay();
	uint Crash(bool flooded = false);
	Trackdir GetVehicleTrackdir() const;
	TileIndex GetOrderStationLocation(StationID station);
	bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);

	bool IsBus() const;

	int GetCurrentMaxSpeed() const;
	int UpdateSpeed();
	void SetDestTile(TileIndex tile);

protected: // These functions should not be called outside acceleration code.

	/**
	 * Allows to know the power value that this vehicle will use.
	 * @return Power value from the engine in HP, or zero if the vehicle is not powered.
	 */
	inline uint16 GetPower() const
	{
		/* Power is not added for articulated parts */
		if (!this->IsArticulatedPart()) {
			/* Road vehicle power is in units of 10 HP. */
			return 10 * GetVehicleProperty(this, PROP_ROADVEH_POWER, RoadVehInfo(this->engine_type)->power);
		}
		return 0;
	}

	/**
	 * Returns a value if this articulated part is powered.
	 * @return Zero, because road vehicles don't have powered parts.
	 */
	inline uint16 GetPoweredPartPower(const RoadVehicle *head) const
	{
		return 0;
	}

	/**
	 * Allows to know the weight value that this vehicle will use.
	 * @return Weight value from the engine in tonnes.
	 */
	inline uint16 GetWeight() const
	{
		uint16 weight = (CargoSpec::Get(this->cargo_type)->weight * this->cargo.StoredCount()) / 16;

		/* Vehicle weight is not added for articulated parts. */
		if (!this->IsArticulatedPart()) {
			/* Road vehicle weight is in units of 1/4 t. */
			weight += GetVehicleProperty(this, PROP_ROADVEH_WEIGHT, RoadVehInfo(this->engine_type)->weight) / 4;
		}

		return weight;
	}

	/**
	 * Allows to know the tractive effort value that this vehicle will use.
	 * @return Tractive effort value from the engine.
	 */
	inline byte GetTractiveEffort() const
	{
		/* The tractive effort coefficient is in units of 1/256.  */
		return GetVehicleProperty(this, PROP_ROADVEH_TRACTIVE_EFFORT, RoadVehInfo(this->engine_type)->tractive_effort);
	}

	/**
	 * Gets the area used for calculating air drag.
	 * @return Area of the engine in m^2.
	 */
	inline byte GetAirDragArea() const
	{
		return 6;
	}

	/**
	 * Gets the air drag coefficient of this vehicle.
	 * @return Air drag value from the engine.
	 */
	inline byte GetAirDrag() const
	{
		return RoadVehInfo(this->engine_type)->air_drag;
	}

	/**
	 * Checks the current acceleration status of this vehicle.
	 * @return Acceleration status.
	 */
	inline AccelStatus GetAccelerationStatus() const
	{
		return (this->vehstatus & VS_STOPPED) ? AS_BRAKE : AS_ACCEL;
	}

	/**
	 * Calculates the current speed of this vehicle.
	 * @return Current speed in km/h-ish.
	 */
	inline uint16 GetCurrentSpeed() const
	{
		return this->cur_speed / 2;
	}

	/**
	 * Returns the rolling friction coefficient of this vehicle.
	 * @return Rolling friction coefficient in [1e-4].
	 */
	inline uint32 GetRollingFriction() const
	{
		/* Trams have a slightly greater friction coefficient than trains.
		 * The rest of road vehicles have bigger values. */
		uint32 coeff = RoadTypeIsTram(this->roadtype) ? 40 : 75;
		/* The friction coefficient increases with speed in a way that
		 * it doubles at 128 km/h, triples at 256 km/h and so on. */
		return coeff * (128 + this->GetCurrentSpeed()) / 128;
	}

	/**
	 * Allows to know the acceleration type of a vehicle.
	 * @return Zero, road vehicles always use a normal acceleration method.
	 */
	inline int GetAccelerationType() const
	{
		return 0;
	}

	/**
	 * Returns the slope steepness used by this vehicle.
	 * @return Slope steepness used by the vehicle.
	 */
	inline uint32 GetSlopeSteepness() const
	{
		return _settings_game.vehicle.roadveh_slope_steepness;
	}

	/**
	 * Gets the maximum speed allowed by the track for this vehicle.
	 * @return Since roads don't limit road vehicle speed, it returns always zero.
	 */
	inline uint16 GetMaxTrackSpeed() const
	{
		return GetRoadTypeInfo(GetRoadType(this->tile, GetRoadTramType(this->roadtype)))->max_speed;
	}

	/**
	 * Checks if the vehicle is at a tile that can be sloped.
	 * @return True if the tile can be sloped.
	 */
	inline bool TileMayHaveSlopedTrack() const
	{
		TrackStatus ts = GetTileTrackStatus(this->tile, TRANSPORT_ROAD, GetRoadTramType(this->roadtype));
		TrackBits trackbits = TrackStatusToTrackBits(ts);

		return trackbits == TRACK_BIT_X || trackbits == TRACK_BIT_Y;
	}

	/**
	 * Road vehicles have to use GetSlopePixelZ() to compute their height
	 * if they are reversing because in that case, their direction
	 * is not parallel with the road. It is safe to return \c true
	 * even if it is not reversing.
	 * @return are we (possibly) reversing?
	 */
	inline bool HasToUseGetSlopePixelZ()
	{
		const RoadVehicle *rv = this->First();

		/* Check if this vehicle is in the same direction as the road under.
		 * We already know it has either GVF_GOINGUP_BIT or GVF_GOINGDOWN_BIT set. */

		if (rv->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)rv->state)) {
			/* If the first vehicle is reversing, this vehicle may be reversing too
			 * (especially if this is the first, and maybe the only, vehicle).*/
			return true;
		}

		while (rv != this) {
			/* If any previous vehicle has different direction,
			 * we may be in the middle of reversing. */
			if (this->direction != rv->direction) return true;
			rv = rv->Next();
		}

		return false;
	}
};

#endif /* ROADVEH_H */