Changeset - r5868:bc3e720ec5f7
[Not reviewed]
master
0 12 0
belugas - 17 years ago 2007-01-30 11:53:35
belugas@openttd.org
(svn r8455) -Codechange: Give a more meaningful name (railveh_type)to member flags of RailVehInfo, as well as changing the code to reflect the fact that it was not a flag but rather a one value only variable. Doing so, some evaluations have been simplified.
-Codechange: Add and use RAILVEH_SINGLEHEAD when railveh_type is set to 0, which was implicit before.
-Cleanup: Remove some extraneous parenthesis.
12 files changed with 89 insertions and 86 deletions:
0 comments (0 inline, 0 general)
src/ai/default/default.cpp
Show inline comments
 
@@ -134,26 +134,26 @@ static void AiStateVehLoop(Player *p)
 
static EngineID AiChooseTrainToBuild(RailType railtype, int32 money, byte flag, TileIndex tile)
 
{
 
	EngineID best_veh_index = INVALID_ENGINE;
 
	byte best_veh_score = 0;
 
	int32 ret;
 
	EngineID i;
 

	
 
	for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
 
		const RailVehicleInfo *rvi = RailVehInfo(i);
 
		const Engine* e = GetEngine(i);
 

	
 
		if (!IsCompatibleRail(rvi->railtype, railtype) ||
 
				rvi->flags & RVI_WAGON ||
 
				(rvi->flags & RVI_MULTIHEAD && flag & 1) ||
 
				rvi->railveh_type == RAILVEH_WAGON ||
 
				(rvi->railveh_type == RAILVEH_MULTIHEAD && flag & 1) ||
 
				!HASBIT(e->player_avail, _current_player) ||
 
				e->reliability < 0x8A3D) {
 
			continue;
 
		}
 

	
 
		ret = DoCommand(tile, i, 0, 0, CMD_BUILD_RAIL_VEHICLE);
 
		if (!CmdFailed(ret) && ret <= money && rvi->ai_rank >= best_veh_score) {
 
			best_veh_score = rvi->ai_rank;
 
			best_veh_index = i;
 
		}
 
	}
 

	
 
@@ -2357,25 +2357,25 @@ static EngineID AiFindBestWagon(CargoID 
 
{
 
	EngineID best_veh_index = INVALID_ENGINE;
 
	EngineID i;
 
	uint16 best_capacity = 0;
 
	uint16 best_speed    = 0;
 
	uint speed;
 

	
 
	for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
 
		const RailVehicleInfo *rvi = RailVehInfo(i);
 
		const Engine* e = GetEngine(i);
 

	
 
		if (!IsCompatibleRail(rvi->railtype, railtype) ||
 
				!(rvi->flags & RVI_WAGON) ||
 
				rvi->railveh_type != RAILVEH_WAGON ||
 
				!HASBIT(e->player_avail, _current_player)) {
 
			continue;
 
		}
 

	
 
		if (rvi->cargo_type != cargo) continue;
 

	
 
		/* max_speed of 0 indicates no speed limit */
 
		speed = rvi->max_speed == 0 ? 0xFFFF : rvi->max_speed;
 

	
 
		if (rvi->capacity >= best_capacity && speed >= best_speed) {
 
			best_capacity = rvi->capacity;
 
			best_speed    = best_speed;
src/autoreplace_gui.cpp
Show inline comments
 
@@ -54,25 +54,25 @@ static void train_engine_drawing_loop(in
 
		if (!EngineHasReplacementForPlayer(p, i) && p->num_engines[i] == 0 && show_outdated) continue;
 

	
 
		if ((rvi->power == 0 && !show_cars) || (rvi->power != 0 && show_cars))  // show wagons or engines (works since wagons do not have power)
 
			continue;
 

	
 
		if (*sel == 0) *selected_id = j;
 

	
 

	
 
		colour = *sel == 0 ? 0xC : 0x10;
 
		if (!(ENGINE_AVAILABLE && show_outdated && RailVehInfo(i)->power && IsCompatibleRail(rvi->railtype, railtype))) {
 
			if ((!IsCompatibleRail(rvi->railtype, railtype) && show_compatible)
 
				|| (rvi->railtype != railtype && !show_compatible)
 
				|| !(rvi->flags & RVI_WAGON) != is_engine ||
 
				|| (rvi->railveh_type != RAILVEH_WAGON) != is_engine ||
 
				!HASBIT(e->player_avail, _local_player))
 
				continue;
 
#if 0
 
		} else {
 
			// TODO find a nice red colour for vehicles being replaced
 
			if ( _autoreplace_array[i] != i )
 
				colour = *sel == 0 ? 0x44 : 0x45;
 
#endif
 
		}
 

	
 
		if (IS_INT_INSIDE(--*pos, -lines_drawn, 0)) {
 
			DrawString(*x + 59, *y + 2, GetCustomEngineName(i),
src/build_vehicle_gui.cpp
Show inline comments
 
@@ -178,38 +178,38 @@ static int CDECL TrainEngineSpeedSorter(
 
	int va = RailVehInfo(*(const EngineID*)a)->max_speed;
 
	int vb = RailVehInfo(*(const EngineID*)b)->max_speed;
 
	int r = va - vb;
 

	
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL TrainEnginePowerSorter(const void *a, const void *b)
 
{
 
	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
 
	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
 

	
 
	int va = rvi_a->power << (rvi_a->flags & RVI_MULTIHEAD ? 1 : 0);
 
	int vb = rvi_b->power << (rvi_b->flags & RVI_MULTIHEAD ? 1 : 0);
 
	int va = rvi_a->power << (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 1 : 0);
 
	int vb = rvi_b->power << (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 1 : 0);
 
	int r = va - vb;
 

	
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL TrainEngineRunningCostSorter(const void *a, const void *b)
 
{
 
	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
 
	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
 

	
 
	int va = rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class] * (rvi_a->flags & RVI_MULTIHEAD ? 2 : 1);
 
	int vb = rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class] * (rvi_b->flags & RVI_MULTIHEAD ? 2 : 1);
 
	int va = rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class] * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
 
	int vb = rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class] * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
 
	int r = va - vb;
 

	
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL TrainEnginePowerVsRunningCostSorter(const void *a, const void *b)
 
{
 
	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
 
	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
 

	
 
	/* Here we are using a few tricks to get the right sort.
 
		* We want power/running cost, but since we usually got higher running cost than power and we store the result in an int,
 
@@ -219,26 +219,26 @@ static int CDECL TrainEnginePowerVsRunni
 
		* Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */
 
	int va = (rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class]) / max((uint16)1, rvi_a->power);
 
	int vb = (rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class]) / max((uint16)1, rvi_b->power);
 
	int r = vb - va;
 

	
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL TrainEnginesThenWagonsSorter(const void *a, const void *b)
 
{
 
	EngineID va = *(const EngineID*)a;
 
	EngineID vb = *(const EngineID*)b;
 
	int val_a = ((RailVehInfo(va)->flags & RVI_WAGON) != 0) ? 1 : 0;
 
	int val_b = ((RailVehInfo(vb)->flags & RVI_WAGON) != 0) ? 1 : 0;
 
	int val_a = (RailVehInfo(va)->railveh_type != RAILVEH_WAGON ? 1 : 0);
 
	int val_b = (RailVehInfo(vb)->railveh_type != RAILVEH_WAGON ? 1 : 0);
 
	int r = val_a - val_b;
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 

	
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
/* Aircraft sorting functions */
 

	
 
static int CDECL AircraftEngineCostSorter(const void *a, const void *b)
 
{
 
@@ -379,25 +379,25 @@ static int DrawRailWagonPurchaseInfo(int
 
	/* Wagon speed limit, displayed if above zero */
 
	if (rvi->max_speed > 0 && _patches.wagon_speed_limits) {
 
		SetDParam(0, rvi->max_speed);
 
		DrawString(x,y, STR_PURCHASE_INFO_SPEED, 0);
 
		y += 10;
 
	}
 
	return y;
 
}
 

	
 
/* Draw locomotive specific details */
 
static int DrawRailEnginePurchaseInfo(int x, int y, EngineID engine_number, const RailVehicleInfo *rvi)
 
{
 
	int multihead = (rvi->flags&RVI_MULTIHEAD?1:0);
 
	int multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD ? 1 : 0);
 

	
 
	/* Purchase Cost - Engine weight */
 
	SetDParam(0, rvi->base_cost * (_price.build_railvehicle >> 3) >> 5);
 
	SetDParam(1, rvi->weight << multihead);
 
	DrawString(x,y, STR_PURCHASE_INFO_COST_WEIGHT, 0);
 
	y += 10;
 

	
 
	/* Max speed - Engine power */
 
	SetDParam(0, rvi->max_speed);
 
	SetDParam(1, rvi->power << multihead);
 
	DrawString(x,y, STR_PURCHASE_INFO_SPEED_POWER, 0);
 
	y += 10;
 
@@ -520,36 +520,36 @@ void DrawVehiclePurchaseInfo(int x, int 
 
{
 
	const Engine *e = GetEngine(engine_number);
 
	YearMonthDay ymd;
 
	ConvertDateToYMD(e->intro_date, &ymd);
 
	bool refitable = false;
 

	
 
	switch (e->type) {
 
		case VEH_Train: {
 
			const RailVehicleInfo *rvi = RailVehInfo(engine_number);
 

	
 
			refitable = (EngInfo(engine_number)->refit_mask != 0) && (rvi->capacity > 0);
 

	
 
			if (rvi->flags & RVI_WAGON) {
 
			if (rvi->railveh_type == RAILVEH_WAGON) {
 
				y = DrawRailWagonPurchaseInfo(x, y, engine_number, rvi);
 
			} else {
 
				y = DrawRailEnginePurchaseInfo(x, y, engine_number, rvi);
 
			}
 

	
 
			/* Cargo type + capacity, or N/A */
 
			if (rvi->capacity == 0) {
 
				SetDParam(0, CT_INVALID);
 
				SetDParam(2, STR_EMPTY);
 
			} else {
 
				int multihead = (rvi->flags & RVI_MULTIHEAD ? 1 : 0);
 
				int multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD ? 1 : 0);
 

	
 
				SetDParam(0, rvi->cargo_type);
 
				SetDParam(1, (rvi->capacity * (CountArticulatedParts(engine_number) + 1)) << multihead);
 
				SetDParam(2, refitable ? STR_9842_REFITTABLE : STR_EMPTY);
 
			}
 
			DrawString(x,y, STR_PURCHASE_INFO_CAPACITY, 0);
 
			y += 10;
 
		}
 
			break;
 
		case VEH_Road:
 
			y = DrawRoadVehPurchaseInfo(x, y, engine_number, RoadVehInfo(engine_number));
 
			refitable = true;
 
@@ -557,25 +557,25 @@ void DrawVehiclePurchaseInfo(int x, int 
 
		case VEH_Ship: {
 
			const ShipVehicleInfo *svi = ShipVehInfo(engine_number);
 
			y = DrawShipPurchaseInfo(x, y, engine_number, svi);
 
			refitable = svi->refittable;
 
		} break;
 
		case VEH_Aircraft:
 
			y = DrawAircraftPurchaseInfo(x, y, engine_number, AircraftVehInfo(engine_number));
 
			refitable = true;
 
			break;
 
	}
 

	
 
	/* Draw details, that applies to all types except rail wagons */
 
	if (e->type != VEH_Train || !(RailVehInfo(engine_number)->flags & RVI_WAGON)) {
 
	if (e->type != VEH_Train || RailVehInfo(engine_number)->railveh_type != RAILVEH_WAGON) {
 
		/* Design date - Life length */
 
		SetDParam(0, ymd.year);
 
		SetDParam(1, e->lifelength);
 
		DrawString(x, y, STR_PURCHASE_INFO_DESIGNED_LIFE, 0);
 
		y += 10;
 

	
 
		/* Reliability */
 
		SetDParam(0, e->reliability * 100 >> 16);
 
		DrawString(x, y, STR_PURCHASE_INFO_RELIABILITY, 0);
 
		y += 10;
 
	}
 

	
 
@@ -598,25 +598,25 @@ static void GenerateBuildTrainList(Windo
 

	
 
	/* Make list of all available train engines and wagons.
 
		* Also check to see if the previously selected engine is still available,
 
		* and if not, reset selection to INVALID_ENGINE. This could be the case
 
	* when engines become obsolete and are removed */
 
	for (sel_id = INVALID_ENGINE, eid = 0; eid < NUM_TRAIN_ENGINES; eid++) {
 
		const RailVehicleInfo *rvi = RailVehInfo(eid);
 

	
 
		if (bv->filter.railtype != RAILTYPE_END && !HasPowerOnRail(rvi->railtype, bv->filter.railtype)) continue;
 
		if (!IsEngineBuildable(eid, VEH_Train, _local_player)) continue;
 

	
 
		EngList_Add(&bv->eng_list, eid);
 
		if ((rvi->flags & RVI_WAGON) == 0) {
 
		if (rvi->railveh_type != RAILVEH_WAGON) {
 
			num_engines++;
 
		} else {
 
			num_wagons++;
 
		}
 

	
 
		if (eid == bv->sel_engine) sel_id = eid;
 
	}
 

	
 
	bv->sel_engine = sel_id;
 

	
 
	// make engines first, and then wagons, sorted by ListPositionOfEngine()
 
	_internal_sort_order = false;
 
@@ -817,25 +817,25 @@ static void BuildVehicleClickEvent(Windo
 
			break;
 
		}
 

	
 
		case BUILD_VEHICLE_WIDGET_SORT_TEXT: case BUILD_VEHICLE_WIDGET_SORT_DROPDOWN: // Select sorting criteria dropdown menu
 
			ShowDropDownMenu(w, _sort_listing[VehTypeToIndex(bv->vehicle_type)], bv->sort_criteria, BUILD_VEHICLE_WIDGET_SORT_DROPDOWN, 0, 0);
 
			break;
 

	
 
		case BUILD_VEHICLE_WIDGET_BUILD: {
 
			EngineID sel_eng = bv->sel_engine;
 
			if (sel_eng != INVALID_ENGINE) {
 
				switch (bv->vehicle_type) {
 
					case VEH_Train:
 
						DoCommandP(w->window_number, sel_eng, 0, (RailVehInfo(sel_eng)->flags & RVI_WAGON) ? CcBuildWagon : CcBuildLoco,
 
						DoCommandP(w->window_number, sel_eng, 0, (RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildLoco,
 
								   CMD_BUILD_RAIL_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
 
						break;
 
					case VEH_Road:
 
						DoCommandP(w->window_number, sel_eng, 0, CcBuildRoadVeh, CMD_BUILD_ROAD_VEH | CMD_MSG(STR_9009_CAN_T_BUILD_ROAD_VEHICLE));
 
						break;
 
					case VEH_Ship:
 
						DoCommandP(w->window_number, sel_eng, 0, CcBuildShip, CMD_BUILD_SHIP | CMD_MSG(STR_980D_CAN_T_BUILD_SHIP));
 
						break;
 
					case VEH_Aircraft:
 
						DoCommandP(w->window_number, sel_eng, 0, CcBuildAircraft, CMD_BUILD_AIRCRAFT | CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT));
 
						break;
 
				}
src/engine.cpp
Show inline comments
 
@@ -276,25 +276,25 @@ int32 CmdWantEnginePreview(TileIndex til
 
	if (!IsEngineIndex(p1)) return CMD_ERROR;
 
	e = GetEngine(p1);
 
	if (GetBestPlayer(e->preview_player) != _current_player) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_player);
 

	
 
	return 0;
 
}
 

	
 
// Determine if an engine type is a wagon (and not a loco)
 
static bool IsWagon(EngineID index)
 
{
 
	return index < NUM_TRAIN_ENGINES && RailVehInfo(index)->flags & RVI_WAGON;
 
	return index < NUM_TRAIN_ENGINES && RailVehInfo(index)->railveh_type == RAILVEH_WAGON;
 
}
 

	
 
static void NewVehicleAvailable(Engine *e)
 
{
 
	Vehicle *v;
 
	Player *p;
 
	EngineID index = e - _engines;
 

	
 
	// In case the player didn't build the vehicle during the intro period,
 
	// prevent that player from getting future intro periods for a while.
 
	if (e->flags & ENGINE_INTRODUCING) {
 
		FOR_ALL_PLAYERS(p) {
src/engine.h
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef ENGINE_H
 
#define ENGINE_H
 

	
 
/** @file engine.h */
 

	
 
#include "oldpool.h"
 
#include "rail.h"
 
#include "sound.h"
 

	
 
enum RailVehicleTypes {
 
	RAILVEH_SINGLEHEAD,
 
	RAILVEH_MULTIHEAD,
 
	RAILVEH_WAGON,
 
};
 

	
 
typedef struct RailVehicleInfo {
 
	byte image_index;
 
	byte flags; /* 1=multihead engine, 2=wagon */
 
	RailVehicleTypes railveh_type;
 
	byte base_cost;
 
	RailTypeByte railtype;
 
	uint16 max_speed;
 
	uint16 power;
 
	uint16 weight;
 
	byte running_cost_base;
 
	byte running_cost_class;
 
	byte engclass; // 0: steam, 1: diesel, 2: electric
 
	byte capacity;
 
	CargoID cargo_type;
 
	byte ai_rank;
 
	uint16 pow_wag_power;
 
@@ -109,29 +115,24 @@ typedef struct Engine {
 

	
 
/**
 
 * EngineInfo.misc_flags is a bitmask, with the following values
 
 */
 
enum {
 
	EF_RAIL_TILTS = 0, ///< Rail vehicle tilts in curves (unsupported)
 
	EF_ROAD_TRAM  = 0, ///< Road vehicle is a tram/light rail vehicle (unsup)
 
	EF_USES_2CC   = 1, ///< Vehicle uses two company colours
 
	EF_RAIL_IS_MU = 2, ///< Rail vehicle is a multiple-unit (DMU/EMU)
 
};
 

	
 
enum {
 
	RVI_MULTIHEAD = 1,
 
	RVI_WAGON = 2,
 
};
 

	
 
enum {
 
	NUM_VEHICLE_TYPES = 6
 
};
 

	
 
static const EngineID INVALID_ENGINE = 0xFFFF;
 

	
 

	
 
void AddTypeToEngines(void);
 
void StartupEngines(void);
 

	
 

	
 
void DrawTrainEngine(int x, int y, EngineID engine, SpriteID pal);
 
void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal);
src/engine_gui.cpp
Show inline comments
 
@@ -113,25 +113,25 @@ static const WindowDesc _engine_preview_
 
	EnginePreviewWndProc
 
};
 

	
 

	
 
void ShowEnginePreviewWindow(EngineID engine)
 
{
 
	AllocateWindowDescFront(&_engine_preview_desc, engine);
 
}
 

	
 
static void DrawTrainEngineInfo(EngineID engine, int x, int y, int maxw)
 
{
 
	const RailVehicleInfo *rvi = RailVehInfo(engine);
 
	uint multihead = (rvi->flags & RVI_MULTIHEAD) ? 1 : 0;
 
	uint multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD) ? 1 : 0;
 

	
 
	SetDParam(0, (_price.build_railvehicle >> 3) * rvi->base_cost >> 5);
 
	SetDParam(2, rvi->max_speed);
 
	SetDParam(3, rvi->power << multihead);
 
	SetDParam(1, rvi->weight << multihead);
 

	
 
	SetDParam(4, rvi->running_cost_base * _price.running_rail[rvi->running_cost_class] >> 8 << multihead);
 

	
 
	if (rvi->capacity != 0) {
 
		SetDParam(5, rvi->cargo_type);
 
		SetDParam(6, rvi->capacity << multihead);
 
	} else {
src/newgrf.cpp
Show inline comments
 
@@ -206,28 +206,28 @@ static GRFFile *GetFileByFilename(const 
 

	
 
typedef bool (*VCI_Handler)(uint engine, int numinfo, int prop, byte **buf, int len);
 

	
 
#define FOR_EACH_OBJECT for (i = 0; i < numinfo; i++)
 

	
 
static void dewagonize(int condition, int engine)
 
{
 
	EngineInfo *ei = &_engine_info[engine];
 
	RailVehicleInfo *rvi = &_rail_vehicle_info[engine];
 

	
 
	if (condition != 0) {
 
		ei->unk2 &= ~0x80;
 
		rvi->flags &= ~2;
 
		rvi->railveh_type = RAILVEH_SINGLEHEAD;
 
	} else {
 
		ei->unk2 |= 0x80;
 
		rvi->flags |= 2;
 
		rvi->railveh_type = RAILVEH_WAGON;
 
	}
 
}
 

	
 
static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **bufp, int len)
 
{
 
	EngineInfo *ei = &_engine_info[engine];
 
	RailVehicleInfo *rvi = &_rail_vehicle_info[engine];
 
	byte *buf = *bufp;
 
	int i;
 
	bool ret = false;
 

	
 
	switch (prop) {
 
@@ -256,36 +256,36 @@ static bool RailVehicleChangeInfo(uint e
 
			FOR_EACH_OBJECT {
 
				uint16 speed = grf_load_word(&buf);
 
				if (speed == 0xFFFF) speed = 0;
 

	
 
				rvi[i].max_speed = speed;
 
			}
 
			break;
 

	
 
		case 0x0B: /* Power */
 
			FOR_EACH_OBJECT {
 
				uint16 power = grf_load_word(&buf);
 

	
 
				if (rvi[i].flags & RVI_MULTIHEAD) power /= 2;
 
				if (rvi[i].railveh_type == RAILVEH_MULTIHEAD) power /= 2;
 

	
 
				rvi[i].power = power;
 
				dewagonize(power, engine + i);
 
			}
 
			break;
 

	
 
		case 0x0D: /* Running cost factor */
 
			FOR_EACH_OBJECT {
 
				uint8 runcostfact = grf_load_byte(&buf);
 

	
 
				if (rvi[i].flags & RVI_MULTIHEAD) runcostfact /= 2;
 
				if (rvi[i].railveh_type == RAILVEH_MULTIHEAD) runcostfact /= 2;
 

	
 
				rvi[i].running_cost_base = runcostfact;
 
			}
 
			break;
 

	
 
		case 0x0E: /* Running cost base */
 
			FOR_EACH_OBJECT {
 
				uint32 base = grf_load_dword(&buf);
 

	
 
				switch (base) {
 
					case 0x4C30: rvi[i].running_cost_class = 0; break;
 
					case 0x4C36: rvi[i].running_cost_class = 1; break;
 
@@ -306,37 +306,37 @@ static bool RailVehicleChangeInfo(uint e
 
				 * as an array index, so we need it to be half the original value. */
 
				if (spriteid < 0xFD) spriteid >>= 1;
 

	
 
				rvi[i].image_index = spriteid;
 
			}
 
			break;
 

	
 
		case 0x13: /* Dual-headed */
 
			FOR_EACH_OBJECT {
 
				uint8 dual = grf_load_byte(&buf);
 

	
 
				if (dual != 0) {
 
					if (!(rvi[i].flags & RVI_MULTIHEAD)) {
 
					if (rvi[i].railveh_type != RAILVEH_MULTIHEAD) {
 
						// adjust power and running cost if needed
 
						rvi[i].power /= 2;
 
						rvi[i].running_cost_base /= 2;
 
					}
 
					rvi[i].flags |= RVI_MULTIHEAD;
 
					rvi[i].railveh_type = RAILVEH_MULTIHEAD;
 
				} else {
 
					if (rvi[i].flags & RVI_MULTIHEAD) {
 
					if (rvi[i].railveh_type == RAILVEH_MULTIHEAD) {
 
						// adjust power and running cost if needed
 
						rvi[i].power *= 2;
 
						rvi[i].running_cost_base *= 2;
 
					}
 
					rvi[i].flags &= ~RVI_MULTIHEAD;
 
					rvi[i].railveh_type = RAILVEH_SINGLEHEAD;
 
				}
 
			}
 
			break;
 

	
 
		case 0x14: /* Cargo capacity */
 
			FOR_EACH_OBJECT rvi[i].capacity = grf_load_byte(&buf);
 
			break;
 

	
 
		case 0x15: /* Cargo type */
 
			FOR_EACH_OBJECT {
 
				uint8 ctype = grf_load_byte(&buf);
 

	
 
@@ -3579,25 +3579,25 @@ static void CalculateRefitMasks(void)
 

	
 
		if (cargo_allowed[engine] != 0) {
 
			// Build up the list of cargo types from the set cargo classes.
 
			for (i = 0; i < lengthof(cargo_classes); i++) {
 
				if (HASBIT(cargo_allowed[engine], i)) mask |= cargo_classes[i];
 
				if (HASBIT(cargo_disallowed[engine], i)) not_mask |= cargo_classes[i];
 
			}
 
		} else {
 
			// Don't apply default refit mask to wagons or engines with no capacity
 
			if (xor_mask == 0 && (
 
						GetEngine(engine)->type != VEH_Train || (
 
							RailVehInfo(engine)->capacity != 0 &&
 
							!(RailVehInfo(engine)->flags & RVI_WAGON)
 
							RailVehInfo(engine)->railveh_type != RAILVEH_WAGON
 
						)
 
					)) {
 
				xor_mask = _default_refitmasks[GetEngine(engine)->type - VEH_Train];
 
			}
 
		}
 
		_engine_info[engine].refit_mask = ((mask & ~not_mask) ^ xor_mask) & _landscape_global_cargo_mask[_opt.landscape];
 
	}
 
}
 

	
 
/* Here we perform initial decoding of some special sprites (as are they
 
 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
 
 * partial implementation yet). */
 
@@ -3792,12 +3792,13 @@ void LoadNewGRF(uint load_index, uint fi
 
				DEBUG(sprite, 2, "Currently %i sprites are loaded", _cur_spriteid);
 
			}
 
		}
 
	}
 

	
 
	// Pre-calculate all refit masks after loading GRF files
 
	CalculateRefitMasks();
 
}
 

	
 

	
 

	
 

	
 

	
src/players.cpp
Show inline comments
 
@@ -647,25 +647,25 @@ byte GetPlayerRailtypes(PlayerID p)
 
{
 
	byte rt = 0;
 
	EngineID i;
 

	
 
	for (i = 0; i != TOTAL_NUM_ENGINES; i++) {
 
		const Engine* e = GetEngine(i);
 
		const EngineInfo *ei = EngInfo(i);
 

	
 
		if (e->type == VEH_Train && HASBIT(ei->climates, _opt.landscape) &&
 
				(HASBIT(e->player_avail, p) || _date >= e->intro_date + 365)) {
 
			const RailVehicleInfo *rvi = RailVehInfo(i);
 

	
 
			if (!(rvi->flags & RVI_WAGON)) {
 
			if (rvi->railveh_type != RAILVEH_WAGON) {
 
				assert(rvi->railtype < RAILTYPE_END);
 
				SETBIT(rt, rvi->railtype);
 
			}
 
		}
 
	}
 

	
 
	return rt;
 
}
 

	
 
static void DeletePlayerStuff(PlayerID pi)
 
{
 
	Player *p;
src/table/engines.h
Show inline comments
 
@@ -320,66 +320,67 @@ const EngineInfo orig_engine_info[] = {
 
 * @param d max_speed (kph)
 
 * @param e power (hp)
 
 * @param f weight
 
 * @param g running_cost_base
 
 * @param h running_cost_class / engclass
 
 * @param i capacity
 
 * @param j cargo_type
 
 * @param k ai_rank
 
 * @param l railtype
 
 * Tractive effort coefficient by default is the same as TTDPatch, 0.30*256=76
 
 */
 
#define RVI(a, b, c, d, e, f, g, h, i, j, k, l) { a, b, c, {l}, d, e, f, g, h, h, i, j, k, 0, 0, 0, 0, 76, 0 }
 
#define M RVI_MULTIHEAD
 
#define W RVI_WAGON
 
#define M RAILVEH_MULTIHEAD
 
#define W RAILVEH_WAGON
 
#define G RAILVEH_SINGLEHEAD
 
#define S 0
 
#define D 1
 
#define E 2
 

	
 
#define R RAILTYPE_RAIL
 
#define C RAILTYPE_ELECTRIC
 
#define O RAILTYPE_MONO
 
#define L RAILTYPE_MAGLEV
 

	
 
const RailVehicleInfo orig_rail_vehicle_info[NUM_TRAIN_ENGINES] = {
 
	//   image_index  max_speed (kph)      running_cost_base
 
	//   |  flags     |        power (hp)  |  running_cost_class & engclass
 
	//   |  |    base_cost     |    weight |  |   capacity
 
	//   |  |    |    |        |    |      |  |   |  cargo_type
 
	//   |  |    |    |        |    |      |  |   |  |
 
	RVI( 2, 0,   7,  64,     300,  47,    50, S,  0, 0              ,  1, R), //   0
 
	RVI(19, 0,   8,  80,     600,  65,    65, D,  0, 0              ,  4, R), //   1
 
	RVI( 2, 0,  10,  72,     400,  85,    90, S,  0, 0              ,  7, R), //   2
 
	RVI( 0, 0,  15,  96,     900, 130,   130, S,  0, 0              , 19, R), //   3
 
	RVI( 1, 0,  19, 112,    1000, 140,   145, S,  0, 0              , 20, R), //   4
 
	RVI(12, 0,  16, 120,    1400,  95,   125, D,  0, 0              , 30, R), //   5
 
	RVI(14, 0,  20, 152,    2000, 120,   135, D,  0, 0              , 31, R), //   6
 
	RVI( 3, 0,  14,  88,    1100, 145,   130, S,  0, 0              , 19, R), //   7
 
	RVI( 0, 0,  13, 112,    1000, 131,   120, S,  0, 0              , 20, R), //   8
 
	RVI( 1, 0,  19, 128,    1200, 162,   140, S,  0, 0              , 21, R), //   9
 
	RVI( 0, 0,  22, 144,    1600, 170,   130, S,  0, 0              , 22, R), //  10
 
	RVI( 2, G,   7,  64,     300,  47,    50, S,  0, 0              ,  1, R), //   0
 
	RVI(19, G,   8,  80,     600,  65,    65, D,  0, 0              ,  4, R), //   1
 
	RVI( 2, G,  10,  72,     400,  85,    90, S,  0, 0              ,  7, R), //   2
 
	RVI( 0, G,  15,  96,     900, 130,   130, S,  0, 0              , 19, R), //   3
 
	RVI( 1, G,  19, 112,    1000, 140,   145, S,  0, 0              , 20, R), //   4
 
	RVI(12, G,  16, 120,    1400,  95,   125, D,  0, 0              , 30, R), //   5
 
	RVI(14, G,  20, 152,    2000, 120,   135, D,  0, 0              , 31, R), //   6
 
	RVI( 3, G,  14,  88,    1100, 145,   130, S,  0, 0              , 19, R), //   7
 
	RVI( 0, G,  13, 112,    1000, 131,   120, S,  0, 0              , 20, R), //   8
 
	RVI( 1, G,  19, 128,    1200, 162,   140, S,  0, 0              , 21, R), //   9
 
	RVI( 0, G,  22, 144,    1600, 170,   130, S,  0, 0              , 22, R), //  10
 
	RVI( 8, M,  11, 112,   600/2,32/2,  85/2, D, 38, CT_PASSENGERS  , 10, R), //  11
 
	RVI(10, M,  14, 120,   700/2,38/2,  70/2, D, 40, CT_PASSENGERS  , 11, R), //  12
 
	RVI( 4, 0,  15, 128,    1250,  72,    95, D,  0, 0              , 30, R), //  13
 
	RVI( 5, 0,  17, 144,    1750, 101,   120, D,  0, 0              , 31, R), //  14
 
	RVI( 4, 0,  18, 160,    2580, 112,   140, D,  0, 0              , 32, R), //  15
 
	RVI(14, 0,  23,  96,    4000, 150,   135, D,  0, 0              , 33, R), //  16
 
	RVI(12, 0,  16, 112,    2400, 120,   105, D,  0, 0              , 34, R), //  17
 
	RVI(13, 0,  30, 112,    6600, 207,   155, D,  0, 0              , 35, R), //  18
 
	RVI(15, 0,  18, 104,    1500, 110,   105, D,  0, 0              , 29, R), //  19
 
	RVI( 4, G,  15, 128,    1250,  72,    95, D,  0, 0              , 30, R), //  13
 
	RVI( 5, G,  17, 144,    1750, 101,   120, D,  0, 0              , 31, R), //  14
 
	RVI( 4, G,  18, 160,    2580, 112,   140, D,  0, 0              , 32, R), //  15
 
	RVI(14, G,  23,  96,    4000, 150,   135, D,  0, 0              , 33, R), //  16
 
	RVI(12, G,  16, 112,    2400, 120,   105, D,  0, 0              , 34, R), //  17
 
	RVI(13, G,  30, 112,    6600, 207,   155, D,  0, 0              , 35, R), //  18
 
	RVI(15, G,  18, 104,    1500, 110,   105, D,  0, 0              , 29, R), //  19
 
	RVI(16, M,  35, 160,  3500/2,95/2, 205/2, D,  0, 0              , 45, R), //  20
 
	RVI(18, 0,  21, 104,    2200, 120,   145, D,  0, 0              , 32, R), //  21
 
	RVI(18, G,  21, 104,    2200, 120,   145, D,  0, 0              , 32, R), //  21
 
	RVI( 6, M,  20, 200,  4500/2,70/2, 190/2, D,  4, CT_MAIL        , 50, R), //  22
 
	RVI(20, 0,  26, 160,    3600,  84,   180, E,  0, 0              , 40, C), //  23
 
	RVI(20, 0,  30, 176,    5000,  82,   205, E,  0, 0              , 41, C), //  24
 
	RVI(20, G,  26, 160,    3600,  84,   180, E,  0, 0              , 40, C), //  23
 
	RVI(20, G,  30, 176,    5000,  82,   205, E,  0, 0              , 41, C), //  24
 
	RVI(21, M,  40, 240,  7000/2,90/2, 240/2, E,  0, 0              , 51, C), //  25
 
	RVI(23, M,  43, 264,  8000/2,95/2, 250/2, E,  0, 0              , 52, C), //  26
 
	RVI(33, W, 247,   0,       0,  25,     0, 0, 40, CT_PASSENGERS  ,  0, R), //  27
 
	RVI(35, W, 228,   0,       0,  21,     0, 0, 30, CT_MAIL        ,  0, R), //  28
 
	RVI(34, W, 176,   0,       0,  18,     0, 0, 30, CT_COAL        ,  0, R), //  29
 
	RVI(36, W, 200,   0,       0,  24,     0, 0, 30, CT_OIL         ,  0, R), //  30
 
	RVI(37, W, 192,   0,       0,  20,     0, 0, 25, CT_LIVESTOCK   ,  0, R), //  31
 
	RVI(38, W, 190,   0,       0,  21,     0, 0, 25, CT_GOODS       ,  0, R), //  32
 
	RVI(39, W, 182,   0,       0,  19,     0, 0, 30, CT_GRAIN       ,  0, R), //  33
 
	RVI(40, W, 181,   0,       0,  16,     0, 0, 30, CT_WOOD        ,  0, R), //  34
 
	RVI(41, W, 179,   0,       0,  19,     0, 0, 30, CT_IRON_ORE    ,  0, R), //  35
 
	RVI(42, W, 196,   0,       0,  18,     0, 0, 20, CT_STEEL       ,  0, R), //  36
 
@@ -391,27 +392,27 @@ const RailVehicleInfo orig_rail_vehicle_
 
	RVI(48, W, 182,   0,       0,  18,     0, 0, 25, CT_FRUIT       ,  0, R), //  42
 
	RVI(49, W, 185,   0,       0,  19,     0, 0, 21, CT_RUBBER      ,  0, R), //  43
 
	RVI(50, W, 176,   0,       0,  19,     0, 0, 30, CT_SUGAR       ,  0, R), //  44
 
	RVI(51, W, 178,   0,       0,  20,     0, 0, 30, CT_COTTON_CANDY,  0, R), //  45
 
	RVI(52, W, 192,   0,       0,  20,     0, 0, 30, CT_TOFFEE      ,  0, R), //  46
 
	RVI(53, W, 190,   0,       0,  21,     0, 0, 20, CT_BUBBLES     ,  0, R), //  47
 
	RVI(54, W, 182,   0,       0,  24,     0, 0, 25, CT_COLA        ,  0, R), //  48
 
	RVI(55, W, 181,   0,       0,  21,     0, 0, 25, CT_CANDY       ,  0, R), //  49
 
	RVI(56, W, 183,   0,       0,  21,     0, 0, 20, CT_TOYS        ,  0, R), //  50
 
	RVI(57, W, 196,   0,       0,  18,     0, 0, 22, CT_BATTERIES   ,  0, R), //  51
 
	RVI(58, W, 193,   0,       0,  18,     0, 0, 25, CT_FIZZY_DRINKS,  0, R), //  52
 
	RVI(59, W, 191,   0,       0,  18,     0, 0, 30, CT_PLASTIC     ,  0, R), //  53
 
	RVI(25, 0,  52, 304,    9000,  95,   230, E,  0, 0              , 60, O), //  54
 
	RVI(25, G,  52, 304,    9000,  95,   230, E,  0, 0              , 60, O), //  54
 
	RVI(26, M,  60, 336, 10000/2,85/2, 240/2, E, 25, CT_PASSENGERS  , 62, O), //  55
 
	RVI(26, 0,  53, 320,    5000,  95,   230, E,  0, 0              , 63, O), //  56
 
	RVI(26, G,  53, 320,    5000,  95,   230, E,  0, 0              , 63, O), //  56
 
	RVI(60, W, 247,   0,       0,  25,     0, 0, 45, CT_PASSENGERS  ,  0, O), //  57
 
	RVI(62, W, 228,   0,       0,  21,     0, 0, 35, CT_MAIL        ,  0, O), //  58
 
	RVI(61, W, 176,   0,       0,  18,     0, 0, 35, CT_COAL        ,  0, O), //  59
 
	RVI(63, W, 200,   0,       0,  24,     0, 0, 35, CT_OIL         ,  0, O), //  60
 
	RVI(64, W, 192,   0,       0,  20,     0, 0, 30, CT_LIVESTOCK   ,  0, O), //  61
 
	RVI(65, W, 190,   0,       0,  21,     0, 0, 30, CT_GOODS       ,  0, O), //  62
 
	RVI(66, W, 182,   0,       0,  19,     0, 0, 35, CT_GRAIN       ,  0, O), //  63
 
	RVI(67, W, 181,   0,       0,  16,     0, 0, 35, CT_WOOD        ,  0, O), //  64
 
	RVI(68, W, 179,   0,       0,  19,     0, 0, 35, CT_IRON_ORE    ,  0, O), //  65
 
	RVI(69, W, 196,   0,       0,  18,     0, 0, 25, CT_STEEL       ,  0, O), //  66
 
	RVI(70, W, 255,   0,       0,  30,     0, 0, 25, CT_VALUABLES   ,  0, O), //  67
 
	RVI(71, W, 191,   0,       0,  22,     0, 0, 30, CT_FOOD        ,  0, O), //  68
 
@@ -421,29 +422,29 @@ const RailVehicleInfo orig_rail_vehicle_
 
	RVI(48, W, 182,   0,       0,  18,     0, 0, 30, CT_FRUIT       ,  0, O), //  72
 
	RVI(49, W, 185,   0,       0,  19,     0, 0, 26, CT_RUBBER      ,  0, O), //  73
 
	RVI(50, W, 176,   0,       0,  19,     0, 0, 35, CT_SUGAR       ,  0, O), //  74
 
	RVI(51, W, 178,   0,       0,  20,     0, 0, 35, CT_COTTON_CANDY,  0, O), //  75
 
	RVI(52, W, 192,   0,       0,  20,     0, 0, 35, CT_TOFFEE      ,  0, O), //  76
 
	RVI(53, W, 190,   0,       0,  21,     0, 0, 25, CT_BUBBLES     ,  0, O), //  77
 
	RVI(54, W, 182,   0,       0,  24,     0, 0, 30, CT_COLA        ,  0, O), //  78
 
	RVI(55, W, 181,   0,       0,  21,     0, 0, 30, CT_CANDY       ,  0, O), //  79
 
	RVI(56, W, 183,   0,       0,  21,     0, 0, 25, CT_TOYS        ,  0, O), //  80
 
	RVI(57, W, 196,   0,       0,  18,     0, 0, 27, CT_BATTERIES   ,  0, O), //  81
 
	RVI(58, W, 193,   0,       0,  18,     0, 0, 30, CT_FIZZY_DRINKS,  0, O), //  82
 
	RVI(59, W, 191,   0,       0,  18,     0, 0, 35, CT_PLASTIC     ,  0, O), //  83
 
	RVI(28, 0,  70, 400,   10000, 105,   250, E,  0, 0              , 70, L), //  84
 
	RVI(29, 0,  74, 448,   12000, 120,   253, E,  0, 0              , 71, L), //  85
 
	RVI(30, 0,  82, 480,   15000, 130,   254, E,  0, 0              , 72, L), //  86
 
	RVI(28, G,  70, 400,   10000, 105,   250, E,  0, 0              , 70, L), //  84
 
	RVI(29, G,  74, 448,   12000, 120,   253, E,  0, 0              , 71, L), //  85
 
	RVI(30, G,  82, 480,   15000, 130,   254, E,  0, 0              , 72, L), //  86
 
	RVI(31, M,  95, 640, 20000/2,150/2,255/2, E,  0, 0              , 73, L), //  87
 
	RVI(28, 0,  70, 480,   10000, 120,   250, E,  0, 0              , 74, L), //  88
 
	RVI(28, G,  70, 480,   10000, 120,   250, E,  0, 0              , 74, L), //  88
 
	RVI(60, W, 247,   0,       0,  25,     0, 0, 47, CT_PASSENGERS  ,  0, L), //  89
 
	RVI(62, W, 228,   0,       0,  21,     0, 0, 37, CT_MAIL        ,  0, L), //  90
 
	RVI(61, W, 176,   0,       0,  18,     0, 0, 37, CT_COAL        ,  0, L), //  91
 
	RVI(63, W, 200,   0,       0,  24,     0, 0, 37, CT_OIL         ,  0, L), //  92
 
	RVI(64, W, 192,   0,       0,  20,     0, 0, 32, CT_LIVESTOCK   ,  0, L), //  93
 
	RVI(65, W, 190,   0,       0,  21,     0, 0, 32, CT_GOODS       ,  0, L), //  94
 
	RVI(66, W, 182,   0,       0,  19,     0, 0, 37, CT_GRAIN       ,  0, L), //  95
 
	RVI(67, W, 181,   0,       0,  16,     0, 0, 37, CT_WOOD        ,  0, L), //  96
 
	RVI(68, W, 179,   0,       0,  19,     0, 0, 37, CT_IRON_ORE    ,  0, L), //  97
 
	RVI(69, W, 196,   0,       0,  18,     0, 0, 27, CT_STEEL       ,  0, L), //  98
 
	RVI(70, W, 255,   0,       0,  30,     0, 0, 27, CT_VALUABLES   ,  0, L), //  99
 
	RVI(71, W, 191,   0,       0,  22,     0, 0, 32, CT_FOOD        ,  0, L), // 100
 
@@ -461,24 +462,25 @@ const RailVehicleInfo orig_rail_vehicle_
 
	RVI(56, W, 183,   0,       0,  21,     0, 0, 27, CT_TOYS        ,  0, L), // 112
 
	RVI(57, W, 196,   0,       0,  18,     0, 0, 29, CT_BATTERIES   ,  0, L), // 113
 
	RVI(58, W, 193,   0,       0,  18,     0, 0, 32, CT_FIZZY_DRINKS,  0, L), // 114
 
	RVI(59, W, 191,   0,       0,  18,     0, 0, 37, CT_PLASTIC     ,  0, L), // 115
 
};
 
#undef L
 
#undef O
 
#undef C
 
#undef R
 
#undef E
 
#undef D
 
#undef S
 
#undef G
 
#undef W
 
#undef M
 
#undef RVI
 

	
 
/** Writes the properties of a ship into the ShipVehicleInfo struct.
 
 * @see ShipVehicleInfo
 
 * @param a image_index
 
 * @param b base_cost
 
 * @param c max_speed
 
 * @param d cargo_type
 
 * @param e cargo_amount
 
 * @param f running_cost
src/train_cmd.cpp
Show inline comments
 
@@ -185,48 +185,47 @@ void TrainConsistChanged(Vehicle* v)
 

	
 
		if (!IsArticulatedPart(u)) {
 
			// check if its a powered wagon
 
			CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
 

	
 
			/* Check powered wagon / visual effect callback */
 
			if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_WAGON_POWER)) {
 
				uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u);
 

	
 
				if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
 
			}
 

	
 
			if ((rvi_v->pow_wag_power != 0) && (rvi_u->flags & RVI_WAGON) && UsesWagonOverride(u)) {
 
				if (u->u.rail.cached_vis_effect < 0x40) {
 
					/* wagon is powered */
 
					SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
 
				}
 
			if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
 
				UsesWagonOverride(u) && (u->u.rail.cached_vis_effect < 0x40)) {
 
				/* wagon is powered */
 
				SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
 
			}
 

	
 
			/* Do not count powered wagons for the compatible railtypes, as wagons always
 
			   have railtype normal */
 
			if (rvi_u->power > 0) {
 
				v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes;
 
			}
 

	
 
			/* Some electric engines can be allowed to run on normal rail. It happens to all
 
			 * existing electric engines when elrails are disabled and then re-enabled */
 
			if (HASBIT(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) {
 
				u->u.rail.railtype = RAILTYPE_RAIL;
 
				u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL);
 
			}
 

	
 
			// max speed is the minimum of the speed limits of all vehicles in the consist
 
			if (!(rvi_u->flags & RVI_WAGON) || _patches.wagon_speed_limits)
 
				if (rvi_u->max_speed != 0 && !UsesWagonOverride(u))
 
					max_speed = min(rvi_u->max_speed, max_speed);
 
			if ((rvi_u->railveh_type != RAILVEH_WAGON || _patches.wagon_speed_limits) &&
 
				rvi_u->max_speed != 0 && !UsesWagonOverride(u))
 
				max_speed = min(rvi_u->max_speed, max_speed);
 
		}
 

	
 
		// check the vehicle length (callback)
 
		veh_len = CALLBACK_FAILED;
 
		if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
 
			veh_len = GetVehicleCallback(CBID_TRAIN_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
 
		}
 
		if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
 
		veh_len = clamp(veh_len, 0, u->next == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
 
		u->u.rail.cached_veh_length = 8 - veh_len;
 
		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
 

	
 
@@ -481,25 +480,25 @@ void DrawTrainEngine(int x, int y, Engin
 
	if (is_custom_sprite(img)) {
 
		image = GetCustomVehicleIcon(engine, DIR_W);
 
		if (image == 0) {
 
			img = orig_rail_vehicle_info[engine].image_index;
 
		} else {
 
			y += _traininfo_vehicle_pitch;
 
		}
 
	}
 
	if (image == 0) {
 
		image = (6 & _engine_sprite_and[img]) + _engine_sprite_base[img];
 
	}
 

	
 
	if (rvi->flags & RVI_MULTIHEAD) {
 
	if (rvi->railveh_type == RAILVEH_MULTIHEAD) {
 
		DrawSprite(image, pal, x - 14, y);
 
		x += 15;
 
		image = 0;
 
		if (is_custom_sprite(img)) {
 
			image = GetCustomVehicleIcon(engine, DIR_E);
 
			if (image == 0) img = orig_rail_vehicle_info[engine].image_index;
 
		}
 
		if (image == 0) {
 
			image =
 
				((6 + _engine_sprite_add[img + 1]) & _engine_sprite_and[img + 1]) +
 
				_engine_sprite_base[img + 1];
 
		}
 
@@ -756,29 +755,29 @@ int32 CmdBuildRailVehicle(TileIndex tile
 
		if (!IsTileDepotType(tile, TRANSPORT_RAIL)) return CMD_ERROR;
 
		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
 
	}
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 

	
 
	rvi = RailVehInfo(p1);
 

	
 
	/* Check if depot and new engine uses the same kind of tracks */
 
	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
 
	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
 

	
 
	if (rvi->flags & RVI_WAGON) return CmdBuildRailWagon(p1, tile, flags);
 
	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
 

	
 
	value = EstimateTrainCost(rvi);
 

	
 
	num_vehicles = (rvi->flags & RVI_MULTIHEAD) ? 2 : 1;
 
	num_vehicles = (rvi->railveh_type == RAILVEH_MULTIHEAD) ? 2 : 1;
 
	num_vehicles += CountArticulatedParts(p1);
 

	
 
	if (!(flags & DC_QUERY_COST)) {
 
		Vehicle *vl[12]; // Allow for upto 10 artic parts and dual-heads
 

	
 
		memset(&vl, 0, sizeof(vl));
 

	
 
		if (!AllocateVehicles(vl, num_vehicles) || IsOrderPoolFull())
 
			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
 

	
 
		v = vl[0];
 

	
 
@@ -825,25 +824,25 @@ int32 CmdBuildRailVehicle(TileIndex tile
 
			v->date_of_last_service = _date;
 
			v->build_year = _cur_year;
 
			v->type = VEH_Train;
 
			v->cur_image = 0xAC2;
 
			v->random_bits = VehicleRandomBits();
 

	
 
			v->subtype = 0;
 
			SetFrontEngine(v);
 
			SetTrainEngine(v);
 

	
 
			VehiclePositionChanged(v);
 

	
 
			if (rvi->flags & RVI_MULTIHEAD) {
 
			if (rvi->railveh_type == RAILVEH_MULTIHEAD) {
 
				SetMultiheaded(v);
 
				AddRearEngineToMultiheadedTrain(vl[0], vl[1], true);
 
				/* Now we need to link the front and rear engines together
 
				 * other_multiheaded_part is the pointer that links to the other half of the engine
 
				 * vl[0] is the front and vl[1] is the rear
 
				 */
 
				vl[0]->u.rail.other_multiheaded_part = vl[1];
 
				vl[1]->u.rail.other_multiheaded_part = vl[0];
 
			} else {
 
				AddArticulatedParts(vl);
 
			}
 

	
 
@@ -1348,25 +1347,25 @@ int32 CmdSellRailWagon(TileIndex tile, u
 

	
 
	// make sure the vehicle is stopped in the depot
 
	if (CheckTrainStoppedInDepot(first) < 0) {
 
		return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
 
	}
 

	
 
	if (IsMultiheaded(v) && !IsTrainEngine(v)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
 

	
 
	if (flags & DC_EXEC) {
 
		if (v == first && IsFrontEngine(first)) {
 
			DeleteWindowById(WC_VEHICLE_VIEW, first->index);
 
		}
 
		if (IsLocalPlayer() && (p1 == 1 || !(RailVehInfo(v->engine_type)->flags & RVI_WAGON))) {
 
		if (IsLocalPlayer() && (p1 == 1 || RailVehInfo(v->engine_type)->railveh_type != RAILVEH_WAGON)) {
 
			InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
 
		}
 
		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
 
		RebuildVehicleLists();
 
	}
 

	
 
	switch (p2) {
 
		case 0: case 2: { /* Delete given wagon */
 
			bool switch_engine = false;    // update second wagon to engine?
 
			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
 

	
 
			/* 1. Delete the engine, if it is dualheaded also delete the matching
 
@@ -2081,25 +2080,25 @@ static void HandleLocomotiveSmokeCloud(c
 
		return;
 

	
 
	u = v;
 

	
 
	do {
 
		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
 
		int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8;
 
		byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
 
		bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6);
 
		int x, y;
 

	
 
		// no smoke?
 
		if ((rvi->flags & RVI_WAGON && effect_type == 0) ||
 
		if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) ||
 
				disable_effect ||
 
				rvi->railtype > RAILTYPE_ELECTRIC ||
 
				v->vehstatus & VS_HIDDEN) {
 
			continue;
 
		}
 

	
 
		// No smoke in depots or tunnels
 
		if (IsTileDepotType(v->tile, TRANSPORT_RAIL) || IsTunnelTile(v->tile)) continue;
 

	
 
		// No sparks for electric vehicles on nonelectrified tracks
 
		if (!HasPowerOnRail(v->u.rail.railtype, GetTileRailType(v->tile, TrackdirToTrack(GetVehicleTrackdir(v))))) continue;
 

	
 
@@ -3743,47 +3742,47 @@ void ConvertOldMultiheadToNew(void)
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_Train) {
 
			if (HASBIT(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
 
				Vehicle *u = v;
 

	
 
				BEGIN_ENUM_WAGONS(u) {
 
					const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
 

	
 
					CLRBIT(u->subtype, 7);
 
					switch (u->subtype) {
 
						case 0: /* TS_Front_Engine */
 
							if (rvi->flags & RVI_MULTIHEAD) SetMultiheaded(u);
 
							if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
 
							SetFrontEngine(u);
 
							SetTrainEngine(u);
 
							break;
 

	
 
						case 1: /* TS_Artic_Part */
 
							u->subtype = 0;
 
							SetArticulatedPart(u);
 
							break;
 

	
 
						case 2: /* TS_Not_First */
 
							u->subtype = 0;
 
							if (rvi->flags & RVI_WAGON) {
 
							if (rvi->railveh_type == RAILVEH_WAGON) {
 
								// normal wagon
 
								SetTrainWagon(u);
 
								break;
 
							}
 
							if (rvi->flags & RVI_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
 
							if (rvi->railveh_type == RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
 
								// rear end of a multiheaded engine
 
								SetMultiheaded(u);
 
								break;
 
							}
 
							if (rvi->flags & RVI_MULTIHEAD) SetMultiheaded(u);
 
							if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
 
							SetTrainEngine(u);
 
							break;
 

	
 
						case 4: /* TS_Free_Car */
 
							u->subtype = 0;
 
							SetTrainWagon(u);
 
							SetFreeWagon(u);
 
							break;
 
						default: NOT_REACHED(); break;
 
					}
 
				} END_ENUM_WAGONS(u)
 
			}
src/train_gui.cpp
Show inline comments
 
@@ -149,25 +149,25 @@ static void TrainViewWndProc(Window *w, 
 
		SetWindowWidgetDisabledState(w,  7, !is_localplayer);
 
		SetWindowWidgetDisabledState(w,  8, !is_localplayer);
 
		SetWindowWidgetDisabledState(w,  9, !is_localplayer);
 
		SetWindowWidgetDisabledState(w, 13, !is_localplayer);
 

	
 
		/* Disable cargo refit button, until we know we can enable it below. */
 
		DisableWindowWidget(w, 12);
 

	
 
		if (is_localplayer) {
 
			/* See if any vehicle can be refitted */
 
			for (u = v; u != NULL; u = u->next) {
 
				if (EngInfo(u->engine_type)->refit_mask != 0 ||
 
						(!(RailVehInfo(v->engine_type)->flags & RVI_WAGON) && v->cargo_cap != 0)) {
 
						(RailVehInfo(v->engine_type)->railveh_type != RAILVEH_WAGON && v->cargo_cap != 0)) {
 
					EnableWindowWidget(w, 12);
 
					/* We have a refittable carriage, bail out */
 
					break;
 
				}
 
			}
 
		}
 

	
 
		/* draw widgets & caption */
 
		SetDParam(0, v->string_id);
 
		SetDParam(1, v->unitnumber);
 
		DrawWindowWidgets(w);
 

	
 
@@ -332,25 +332,25 @@ static void TrainDetailsCargoTab(const V
 
			SetDParam(0, v->cargo_type);
 
			SetDParam(1, num);
 
			SetDParam(2, v->cargo_source);
 
			SetDParam(3, _patches.freight_trains);
 
			str = FreightWagonMult(v->cargo_type) > 1 ? STR_FROM_MULT : STR_8813_FROM;
 
		}
 
		DrawString(x, y, str, 0);
 
	}
 
}
 

	
 
static void TrainDetailsInfoTab(const Vehicle *v, int x, int y)
 
{
 
	if (RailVehInfo(v->engine_type)->flags & RVI_WAGON) {
 
	if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) {
 
		SetDParam(0, GetCustomEngineName(v->engine_type));
 
		SetDParam(1, v->value);
 
		DrawString(x, y, STR_882D_VALUE, 0x10);
 
	} else {
 
		SetDParam(0, GetCustomEngineName(v->engine_type));
 
		SetDParam(1, v->build_year);
 
		SetDParam(2, v->value);
 
		DrawString(x, y, STR_882C_BUILT_VALUE, 0x10);
 
	}
 
}
 

	
 
static void TrainDetailsCapacityTab(const Vehicle *v, int x, int y)
src/vehicle.cpp
Show inline comments
 
@@ -778,25 +778,25 @@ CargoID FindFirstRefittableCargo(EngineI
 
* @param engine Which engine to refit
 
* @return Price for refitting
 
*/
 
int32 GetRefitCost(EngineID engine_type)
 
{
 
	int32 base_cost = 0;
 

	
 
	switch (GetEngine(engine_type)->type) {
 
		case VEH_Ship: base_cost = _price.ship_base; break;
 
		case VEH_Road: base_cost = _price.roadveh_base; break;
 
		case VEH_Aircraft: base_cost = _price.aircraft_base; break;
 
		case VEH_Train:
 
			base_cost = 2 * ((RailVehInfo(engine_type)->flags & RVI_WAGON) ?
 
			base_cost = 2 * ((RailVehInfo(engine_type)->railveh_type == RAILVEH_WAGON) ?
 
							 _price.build_railwagon : _price.build_railvehicle);
 
			break;
 
		default: NOT_REACHED(); break;
 
	}
 
	return (EngInfo(engine_type)->refit_cost * base_cost) >> 10;
 
}
 

	
 
static void DoDrawVehicle(const Vehicle *v)
 
{
 
	SpriteID image = v->cur_image;
 
	SpriteID pal;
 

	
 
@@ -2234,25 +2234,25 @@ static int32 MaybeReplaceVehicle(Vehicle
 
		}
 
		// now we redo the loop, but this time we actually do stuff since we know that we can do it
 
		flags |= DC_EXEC;
 
	}
 

	
 
	/* If setting is on to try not to exceed the old length of the train with the replacement */
 
	if (v->type == VEH_Train && p->renew_keep_length) {
 
		Vehicle *temp;
 
		w = v;
 

	
 
		while (v->u.rail.cached_total_length > old_total_length) {
 
			// the train is too long. We will remove cars one by one from the start of the train until it's short enough
 
			while (w != NULL && !(RailVehInfo(w->engine_type)->flags&RVI_WAGON) ) {
 
			while (w != NULL && RailVehInfo(w->engine_type)->railveh_type != RAILVEH_WAGON) {
 
				w = GetNextVehicle(w);
 
			}
 
			if (w == NULL) {
 
				// we failed to make the train short enough
 
				SetDParam(0, v->unitnumber);
 
				AddNewsItem(STR_TRAIN_TOO_LONG_AFTER_REPLACEMENT, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
 
				break;
 
			}
 
			temp = w;
 
			w = GetNextVehicle(w);
 
			DoCommand(0, (INVALID_VEHICLE << 16) | temp->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
 
			MoveVehicleCargo(v, temp);
 
@@ -2841,25 +2841,25 @@ static SpriteID GetEngineColourMap(Engin
 
	if (p->livery[LS_DEFAULT].in_use && (_patches.liveries == 2 || (_patches.liveries == 1 && player == _local_player))) {
 
		/* Determine the livery scheme to use */
 
		switch (GetEngine(engine_type)->type) {
 
			case VEH_Train: {
 
				const RailVehicleInfo *rvi = RailVehInfo(engine_type);
 

	
 
				switch (rvi->railtype) {
 
					default: NOT_REACHED();
 
					case RAILTYPE_RAIL:
 
					case RAILTYPE_ELECTRIC:
 
					{
 
						if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
 
						if (rvi->flags & RVI_WAGON) {
 
						if (rvi->railveh_type == RAILVEH_WAGON) {
 
							if (cargo_type == CT_PASSENGERS || cargo_type == CT_MAIL || cargo_type == CT_VALUABLES) {
 
								if (parent_engine_type == INVALID_ENGINE) {
 
									scheme = LS_PASSENGER_WAGON_STEAM;
 
								} else {
 
									switch (RailVehInfo(parent_engine_type)->engclass) {
 
										case 0: scheme = LS_PASSENGER_WAGON_STEAM; break;
 
										case 1: scheme = LS_PASSENGER_WAGON_DIESEL; break;
 
										case 2: scheme = LS_PASSENGER_WAGON_ELECTRIC; break;
 
									}
 
								}
 
							} else {
 
								scheme = LS_FREIGHT_WAGON;
0 comments (0 inline, 0 general)