Changeset - r4603:3b159d0db197
[Not reviewed]
master
0 8 1
peter1138 - 18 years ago 2006-09-15 12:27:00
peter1138@openttd.org
(svn r6455) - Feature: Add 2cc (two company colours) livery schemes. This replaces the original colour selection window and bumps the saveload version. Liveries are supported for all vehicles, not just those with 2cc support. Thanks to lakie for GUI inspiration.
9 files changed with 453 insertions and 70 deletions:
0 comments (0 inline, 0 general)
lang/english.txt
Show inline comments
 
@@ -2166,6 +2166,24 @@ STR_707E_OWNED_BY_OWNED_BY              
 
STR_707F_HAS_BEEN_TAKEN_OVER_BY                                 :{BLACK}{BIGFONT}{COMPANY} has been taken over by {COMPANY}!
 
STR_7080_PROTECTED                                              :{WHITE}This company is not old enough to trade shares yet...
 

	
 
STR_LIVERY_DEFAULT                                              :Standard Livery
 
STR_LIVERY_STEAM                                                :Steam Engine
 
STR_LIVERY_DIESEL                                               :Diesel Engine
 
STR_LIVERY_ELECTRIC                                             :Electric Engine
 
STR_LIVERY_MONORAIL                                             :Monorail Engine
 
STR_LIVERY_MAGLEV                                               :Maglev Engine
 
STR_LIVERY_DMU                                                  :DMU
 
STR_LIVERY_EMU                                                  :EMU
 
STR_LIVERY_PASSENGER_WAGON                                      :Passenger Coach
 
STR_LIVERY_FREIGHT_WAGON                                        :Freight Wagon
 
STR_LIVERY_BUS                                                  :Bus
 
STR_LIVERY_TRUCK                                                :Lorry
 
STR_LIVERY_PASSENGER_SHIP                                       :Passenger Ferry
 
STR_LIVERY_FREIGHT_SHIP                                         :Freight Ship
 
STR_LIVERY_HELICOPTER                                           :Helicopter
 
STR_LIVERY_SMALL_PLANE                                          :Small Aeroplane
 
STR_LIVERY_LARGE_PLANE                                          :Large Aeroplane
 

	
 
##id 0x8000
 
STR_8000_KIRBY_PAUL_TANK_STEAM                                  :Kirby Paul Tank (Steam)
 
STR_8001_MJS_250_DIESEL                                         :MJS 250 (Diesel)
livery.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
#ifndef LIVERY_H
 
#define LIVERY_H
 

	
 

	
 
/* List of different livery schemes. */
 
typedef enum LiverySchemes {
 
	LS_DEFAULT,
 

	
 
	/* Rail vehicles */
 
	LS_STEAM,
 
	LS_DIESEL,
 
	LS_ELECTRIC,
 
	LS_MONORAIL,
 
	LS_MAGLEV,
 
	LS_DMU,
 
	LS_EMU,
 
	LS_PASSENGER_WAGON,
 
	LS_FREIGHT_WAGON,
 

	
 
	/* Road vehicles */
 
	LS_BUS,
 
	LS_TRUCK,
 

	
 
	/* Ships */
 
	LS_PASSENGER_SHIP,
 
	LS_FREIGHT_SHIP,
 

	
 
	/* Aircraft */
 
	LS_HELICOPTER,
 
	LS_SMALL_PLANE,
 
	LS_LARGE_PLANE,
 

	
 
	LS_END
 
} LiveryScheme;
 

	
 

	
 
/* List of different livery classes, used only by the livery GUI. */
 
typedef enum LiveryClasses {
 
	LC_OTHER,
 
	LC_RAIL,
 
	LC_ROAD,
 
	LC_SHIP,
 
	LC_AIRCRAFT,
 
	LC_END
 
} LiveryClass;
 

	
 

	
 
typedef struct Livery {
 
	bool in_use;  ///< Set if this livery should be used instead of the default livery.
 
	byte colour1; ///< First colour, for all vehicles.
 
	byte colour2; ///< Second colour, for vehicles with 2CC support.
 
} Livery;
 

	
 
#endif /* LIVERY_H */
 

	
misc_cmd.c
Show inline comments
 
@@ -13,6 +13,7 @@
 
#include "economy.h"
 
#include "network.h"
 
#include "variables.h"
 
#include "livery.h"
 

	
 
/** Change the player's face.
 
 * @param tile unused
 
@@ -30,28 +31,78 @@ int32 CmdSetPlayerFace(TileIndex tile, u
 

	
 
/** Change the player's company-colour
 
 * @param tile unused
 
 * @param p1 unused
 
 * @param p1 bitstuffed:
 
 * p1 bits 0-7 scheme to set
 
 * p1 bits 8-9 set in use state or first/second colour
 
 * @param p2 new colour for vehicles, property, etc.
 
 */
 
int32 CmdSetPlayerColor(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Player *p, *pp;
 
	byte colour;
 
	LiveryScheme scheme = GB(p1, 0, 8);
 
	byte state = GB(p1, 8, 2);
 

	
 
	if (p2 >= 16) return CMD_ERROR; // max 16 colours
 
	colour = p2;
 

	
 
	if (scheme >= LS_END || state >= 3) return CMD_ERROR;
 

	
 
	p = GetPlayer(_current_player);
 

	
 
	/* Ensure no two companies have the same colour */
 
	FOR_ALL_PLAYERS(pp) {
 
		if (pp->is_active && pp != p && pp->player_color == colour)
 
			return CMD_ERROR;
 
	/* Ensure no two companies have the same primary colour */
 
	if (scheme == LS_DEFAULT && state == 0) {
 
		FOR_ALL_PLAYERS(pp) {
 
			if (pp->is_active && pp != p && pp->player_color == colour) return CMD_ERROR;
 
		}
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		_player_colors[_current_player] = colour;
 
		p->player_color = colour;
 
		switch (state) {
 
			case 0:
 
				p->livery[scheme].colour1 = colour;
 

	
 
				/* If setting the first colour of the default scheme, adjust the
 
				 * original and cached player colours too. */
 
				if (scheme == LS_DEFAULT) {
 
					_player_colors[_current_player] = colour;
 
					p->player_color = colour;
 
				}
 
				break;
 

	
 
			case 1:
 
				p->livery[scheme].colour2 = colour;
 
				break;
 

	
 
			case 2:
 
				p->livery[scheme].in_use = colour != 0;
 

	
 
				/* Now handle setting the default scheme's in_use flag.
 
				 * This is different to the other schemes, as it signifies if any
 
				 * scheme is active at all. If this flag is not set, then no
 
				 * processing of vehicle types occurs at all, and only the default
 
				 * colours will be used. */
 

	
 
				/* If enabling a scheme, set the default scheme to be in use too */
 
				if (colour != 0) {
 
					p->livery[LS_DEFAULT].in_use = true;
 
					break;
 
				}
 

	
 
				/* Else loop through all schemes to see if any are left enabled.
 
				 * If not, disable the default scheme too. */
 
				p->livery[LS_DEFAULT].in_use = false;
 
				for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
 
					if (p->livery[scheme].in_use) {
 
						p->livery[LS_DEFAULT].in_use = true;
 
						break;
 
					}
 
				}
 
				break;
 

	
 
			default:
 
				break;
 
		}
 
		MarkWholeScreenDirty();
 
	}
 
	return 0;
openttd.c
Show inline comments
 
@@ -1452,6 +1452,8 @@ bool AfterLoadGame(void)
 

	
 
	YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK);
 

	
 
	if (CheckSavegameVersion(34)) FOR_ALL_PLAYERS(p) ResetPlayerLivery(p);
 

	
 
	FOR_ALL_PLAYERS(p) p->avail_railtypes = GetPlayerRailtypes(p->index);
 

	
 
	if (!CheckSavegameVersion(27)) AfterLoadStations();
player.h
Show inline comments
 
@@ -7,6 +7,7 @@
 
#include "aystar.h"
 
#include "rail.h"
 
#include "engine.h"
 
#include "livery.h"
 

	
 
typedef struct PlayerEconomyEntry {
 
	int32 income;
 
@@ -161,6 +162,7 @@ typedef struct Player {
 
	int64 money64; // internal 64-bit version of the money. the 32-bit field will be clamped to plus minus 2 billion
 

	
 
	byte player_color;
 
	Livery livery[LS_END];
 
	byte player_money_fraction;
 
	byte avail_railtypes;
 
	byte block_preview;
 
@@ -312,4 +314,11 @@ static inline int32 AddEngineReplacement
 
 */
 
static inline int32 RemoveEngineReplacementForPlayer(Player *p, EngineID engine, uint32 flags) {return RemoveEngineReplacement(&p->engine_renew_list, engine, flags); }
 

	
 
/**
 
 * Reset the livery schemes to the player's primary colour.
 
 * This is used on loading games without livery information and on new player start up.
 
 * @param p Player to reset.
 
 */
 
void ResetPlayerLivery(Player *p);
 

	
 
#endif /* PLAYER_H */
player_gui.c
Show inline comments
 
@@ -245,78 +245,223 @@ void ShowPlayerFinances(PlayerID player)
 
	DoShowPlayerFinances(player, false, false);
 
}
 

	
 
static void SelectPlayerColorWndProc(Window *w, WindowEvent *e)
 
/* List of colours for the livery window */
 
static const StringID _colour_dropdown[] = {
 
	STR_00D1_DARK_BLUE,
 
	STR_00D2_PALE_GREEN,
 
	STR_00D3_PINK,
 
	STR_00D4_YELLOW,
 
	STR_00D5_RED,
 
	STR_00D6_LIGHT_BLUE,
 
	STR_00D7_GREEN,
 
	STR_00D8_DARK_GREEN,
 
	STR_00D9_BLUE,
 
	STR_00DA_CREAM,
 
	STR_00DB_MAUVE,
 
	STR_00DC_PURPLE,
 
	STR_00DD_ORANGE,
 
	STR_00DE_BROWN,
 
	STR_00DF_GREY,
 
	STR_00E0_WHITE,
 
	INVALID_STRING_ID
 
};
 

	
 
/* Association of liveries to livery classes */
 
static const LiveryClass livery_class[LS_END] = {
 
	LC_OTHER,
 
	LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL,
 
	LC_ROAD, LC_ROAD,
 
	LC_SHIP, LC_SHIP,
 
	LC_AIRCRAFT, LC_AIRCRAFT, LC_AIRCRAFT,
 
};
 

	
 
/* Number of liveries in each class, used to determine the height of the livery window */
 
static const byte livery_height[] = {
 
	1,
 
	9,
 
	2,
 
	2,
 
	3,
 
};
 

	
 
typedef struct livery_d {
 
	uint32 sel;
 
	LiveryClass livery_class;
 
} livery_d;
 
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(livery_d));
 

	
 
static void ShowColourDropDownMenu(Window *w, uint32 widget)
 
{
 
	uint32 used_colours = 0;
 
	const Livery *livery;
 
	LiveryScheme scheme;
 

	
 
	/* Disallow other player colours for the primary colour */
 
	if (HASBIT(WP(w, livery_d).sel, LS_DEFAULT) && widget == 10) {
 
		const Player *p;
 
		FOR_ALL_PLAYERS(p) {
 
			if (p->is_active && p->index != _local_player) SETBIT(used_colours, p->player_color);
 
		}
 
	}
 

	
 
	/* Get the first selected livery to use as the default dropdown item */
 
	for (scheme = 0; scheme < LS_END; scheme++) {
 
		if (HASBIT(WP(w, livery_d).sel, scheme)) break;
 
	}
 
	if (scheme == LS_END) scheme = LS_DEFAULT;
 
	livery = &GetPlayer(w->window_number)->livery[scheme];
 

	
 
	ShowDropDownMenu(w, _colour_dropdown, widget == 10 ? livery->colour1 : livery->colour2, widget, used_colours, 0);
 
}
 

	
 
static void SelectPlayerLiveryWndProc(Window *w, WindowEvent *e)
 
{
 
	switch (e->event) {
 
	case WE_PAINT: {
 
		const Player *p;
 
		uint used_colors = 0;
 
		int num_free = 16;
 
		int x,y,pos;
 
		int i;
 
		case WE_PAINT: {
 
			const Player *p = GetPlayer(w->window_number);
 
			LiveryScheme scheme = LS_DEFAULT;
 
			int y = 51;
 

	
 
			if ((WP(w, livery_d).sel == 0)) {
 
				/* Disable dropdown controls if no scheme is selected */
 
				w->disabled_state = 1 << 9 | 1 << 10 | 1 << 11 | 1 << 12;
 
			} else {
 
				w->disabled_state = 0;
 
				for (scheme = 0; scheme < LS_END; scheme++) {
 
					if (HASBIT(WP(w, livery_d).sel, scheme)) break;
 
				}
 
				if (scheme == LS_END) scheme = LS_DEFAULT;
 
			}
 

	
 
		FOR_ALL_PLAYERS(p) {
 
			if (p->is_active) {
 
				SETBIT(used_colors, p->player_color);
 
				num_free--;
 
			}
 
		}
 
		WP(w,def_d).data_1 = used_colors;
 
		SetVScrollCount(w, num_free);
 
		DrawWindowWidgets(w);
 
			SetDParam(0, STR_00D1_DARK_BLUE + p->livery[scheme].colour1);
 
			SetDParam(1, STR_00D1_DARK_BLUE + p->livery[scheme].colour2);
 

	
 
			DrawWindowWidgets(w);
 

	
 
			for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
 
				if (livery_class[scheme] == WP(w, livery_d).livery_class) {
 
					bool sel = HASBIT(WP(w, livery_d).sel, scheme) != 0;
 

	
 
		x = 2;
 
		y = 17;
 
		pos = w->vscroll.pos;
 
					if (scheme != LS_DEFAULT) {
 
						DrawSprite(p->livery[scheme].in_use ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, 2, y);
 
					}
 

	
 
					DrawString(15, y, STR_LIVERY_DEFAULT + scheme, sel ? 0xC : 0x10);
 

	
 
					DrawSprite(SPR_SQUARE | GENERAL_SPRITE_COLOR(p->livery[scheme].colour1) | PALETTE_MODIFIER_COLOR, 152, y);
 
					DrawSprite(SPR_SQUARE | GENERAL_SPRITE_COLOR(p->livery[scheme].colour2) | PALETTE_MODIFIER_COLOR, 277, y);
 

	
 
		for (i = 0; i != 16; i++) {
 
			if (!(used_colors & 1) && --pos < 0 && pos >= -8) {
 
				DrawString(x + 30, y, STR_00D1_DARK_BLUE + i, 2);
 
				DrawSprite(GENERAL_SPRITE_COLOR(i) | PALETTE_MODIFIER_COLOR | SPR_VEH_BUS_SIDE_VIEW, x + 14, y + 4);
 
				y += 14;
 
					DrawString(165, y, STR_00D1_DARK_BLUE + p->livery[scheme].colour1, sel ? 0xC : 2);
 
					DrawString(290, y, STR_00D1_DARK_BLUE + p->livery[scheme].colour2, sel ? 0xC : 2);
 

	
 
					y += 14;
 
				}
 
			}
 
			used_colors >>= 1;
 
			break;
 
		}
 
	} break;
 

	
 
	case WE_CLICK:
 
		if (e->click.widget == 2) {
 
			int item = (e->click.pt.y - 13) / 14;
 
			uint used_colors;
 
			int i;
 
		case WE_CLICK: {
 
			switch (e->click.widget) {
 
				/* Livery Class buttons */
 
				case 2:
 
				case 3:
 
				case 4:
 
				case 5:
 
				case 6: {
 
					LiveryScheme scheme;
 

	
 
					WP(w, livery_d).livery_class = e->click.widget - 2;
 
					WP(w, livery_d).sel = 0;
 

	
 
			if ((uint)item >= 8)
 
				return;
 
			item += w->vscroll.pos;
 
			used_colors = WP(w,def_d).data_1;
 

	
 
			for (i = 0; i != 16; i++) {
 
				if (!(used_colors & 1) && --item < 0) {
 
					DoCommandP(0, 0, i, NULL, CMD_SET_PLAYER_COLOR);
 
					DeleteWindow(w);
 
					/* Select the first item in the list */
 
					for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
 
						if (livery_class[scheme] == WP(w, livery_d).livery_class) {
 
							WP(w, livery_d).sel = 1 << scheme;
 
							break;
 
						}
 
					}
 
					w->click_state = 1 << e->click.widget;
 
					w->height = 49 + livery_height[WP(w, livery_d).livery_class] * 14;
 
					w->widget[13].bottom = w->height - 1;
 
					w->widget[13].data = livery_height[WP(w, livery_d).livery_class] << 8 | 1;
 
					MarkWholeScreenDirty();
 
					break;
 
				}
 
				used_colors >>= 1;
 

	
 
				case 9:
 
				case 10: // First colour dropdown
 
					ShowColourDropDownMenu(w, 10);
 
					break;
 

	
 
				case 11:
 
				case 12: // Second colour dropdown
 
					ShowColourDropDownMenu(w, 12);
 
					break;
 

	
 
				case 13: {
 
					LiveryScheme scheme;
 
					LiveryScheme j = (e->click.pt.y - 48) / 14;
 

	
 
					for (scheme = 0; scheme <= j; scheme++) {
 
						if (livery_class[scheme] != WP(w, livery_d).livery_class) j++;
 
						if (scheme >= LS_END) return;
 
					}
 
					if (j >= LS_END) return;
 

	
 
					/* If clicking on the left edge, toggle using the livery */
 
					if (e->click.pt.x < 10) {
 
						DoCommandP(0, j | (2 << 8), !GetPlayer(w->window_number)->livery[j].in_use, NULL, CMD_SET_PLAYER_COLOR);
 
					}
 

	
 
					if (_ctrl_pressed) {
 
						TOGGLEBIT(WP(w, livery_d).sel, j);
 
					} else {
 
						WP(w, livery_d).sel = 1 << j;
 
					}
 
					SetWindowDirty(w);
 
					break;
 
				}
 
			}
 
			break;
 
		}
 
		break;
 

	
 
		case WE_DROPDOWN_SELECT: {
 
			LiveryScheme scheme;
 

	
 
			for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
 
				if (HASBIT(WP(w, livery_d).sel, scheme)) {
 
					DoCommandP(0, scheme | (e->dropdown.button == 10 ? 0 : 256), e->dropdown.index, NULL, CMD_SET_PLAYER_COLOR);
 
				}
 
			}
 
			break;
 
		}
 
	}
 
}
 

	
 
static const Widget _select_player_color_widgets[] = {
 
{   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                  STR_018B_CLOSE_WINDOW},
 
{    WWT_CAPTION,   RESIZE_NONE,    14,    11,   149,     0,    13, STR_7007_NEW_COLOR_SCHEME, STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{     WWT_IMGBTN,   RESIZE_NONE,    14,     0,   137,    14,   127, 0x0,                       STR_7034_CLICK_ON_SELECTED_NEW_COLOR},
 
{  WWT_SCROLLBAR,   RESIZE_NONE,    14,   138,   149,    14,   127, 0x0,                       STR_0190_SCROLL_BAR_SCROLLS_LIST},
 
{   WIDGETS_END},
 
static const Widget _select_player_livery_widgets[] = {
 
{ WWT_CLOSEBOX, RESIZE_NONE, 14,   0,  10,   0,  13, STR_00C5,                  STR_018B_CLOSE_WINDOW },
 
{  WWT_CAPTION, RESIZE_NONE, 14,  11, 399,   0,  13, STR_7007_NEW_COLOR_SCHEME, STR_018C_WINDOW_TITLE_DRAG_THIS },
 
{   WWT_IMGBTN, RESIZE_NONE, 14,   0,  21,  14,  35, SPR_IMG_COMPANY_GENERAL,   STR_NULL },
 
{   WWT_IMGBTN, RESIZE_NONE, 14,  22,  43,  14,  35, SPR_IMG_TRAINLIST,         STR_NULL },
 
{   WWT_IMGBTN, RESIZE_NONE, 14,  44,  65,  14,  35, SPR_IMG_TRUCKLIST,         STR_NULL },
 
{   WWT_IMGBTN, RESIZE_NONE, 14,  66,  87,  14,  35, SPR_IMG_SHIPLIST,          STR_NULL },
 
{   WWT_IMGBTN, RESIZE_NONE, 14,  88, 109,  14,  35, SPR_IMG_AIRPLANESLIST,     STR_NULL },
 
{    WWT_PANEL, RESIZE_NONE, 14, 110, 399,  14,  35, 0x0,                       STR_NULL },
 
{    WWT_PANEL, RESIZE_NONE, 14,   0, 149,  36,  47, 0x0,                       STR_NULL },
 
{  WWT_TEXTBTN, RESIZE_NONE, 14, 150, 262,  36,  47, STR_02BD,                  STR_7007_NEW_COLOR_SCHEME },
 
{  WWT_TEXTBTN, RESIZE_NONE, 14, 263, 274,  36,  47, STR_0225,                  STR_7007_NEW_COLOR_SCHEME },
 
{  WWT_TEXTBTN, RESIZE_NONE, 14, 275, 387,  36,  47, STR_02E1,                  STR_7007_NEW_COLOR_SCHEME },
 
{  WWT_TEXTBTN, RESIZE_NONE, 14, 388, 399,  36,  47, STR_0225,                  STR_7007_NEW_COLOR_SCHEME },
 
{   WWT_MATRIX, RESIZE_NONE, 14,   0, 399,  48,  48 + 1 * 14, (1 << 8) | 1,     STR_NULL },
 
{ WIDGETS_END },
 
};
 

	
 
static const WindowDesc _select_player_color_desc = {
 
	-1,-1, 150, 128,
 
	WC_PLAYER_COLOR,0,
 
static const WindowDesc _select_player_livery_desc = {
 
	-1,-1, 400, 49 + 1 * 14,
 
	WC_PLAYER_COLOR, 0,
 
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
 
	_select_player_color_widgets,
 
	SelectPlayerColorWndProc
 
	_select_player_livery_widgets,
 
	SelectPlayerLiveryWndProc
 
};
 

	
 
static void SelectPlayerFaceWndProc(Window *w, WindowEvent *e)
 
@@ -570,10 +715,12 @@ static void PlayerCompanyWndProc(Window 
 
		} break;
 

	
 
		case 4: {/* change color */
 
			Window *wf = AllocateWindowDescFront(&_select_player_color_desc,w->window_number);
 
			Window *wf = AllocateWindowDescFront(&_select_player_livery_desc, w->window_number);
 
			if (wf != NULL) {
 
				wf->caption_color = wf->window_number;
 
				wf->vscroll.cap = 8;
 
				WP(wf,livery_d).livery_class = LC_OTHER;
 
				WP(wf,livery_d).sel = 1;
 
				wf->click_state = 1 << 2;
 
			}
 
		} break;
 

	
players.c
Show inline comments
 
@@ -481,6 +481,17 @@ static Player *AllocatePlayer(void)
 
	return NULL;
 
}
 

	
 
void ResetPlayerLivery(Player *p)
 
{
 
	LiveryScheme scheme;
 

	
 
	for (scheme = 0; scheme < LS_END; scheme++) {
 
		p->livery[scheme].in_use  = false;
 
		p->livery[scheme].colour1 = p->player_color;
 
		p->livery[scheme].colour2 = p->player_color;
 
	}
 
}
 

	
 
Player *DoStartupNewPlayer(bool is_ai)
 
{
 
	Player *p;
 
@@ -490,6 +501,7 @@ Player *DoStartupNewPlayer(bool is_ai)
 

	
 
	// Make a color
 
	p->player_color = GeneratePlayerColor();
 
	ResetPlayerLivery(p);
 
	_player_colors[p->index] = p->player_color;
 
	p->name_1 = STR_SV_UNNAMED;
 
	p->is_active = true;
 
@@ -1253,6 +1265,13 @@ static const SaveLoad _player_ai_build_r
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _player_livery_desc[] = {
 
	SLE_CONDVAR(Livery, in_use,  SLE_BOOL,  34, SL_MAX_VERSION),
 
	SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
 
	SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
 
	SLE_END()
 
};
 

	
 
static void SaveLoad_PLYR(Player* p)
 
{
 
	int i;
 
@@ -1274,6 +1293,11 @@ static void SaveLoad_PLYR(Player* p)
 
	for (i = 0; i < p->num_valid_stat_ent; i++) {
 
		SlObject(&p->old_economy[i], _player_economy_desc);
 
	}
 

	
 
	// Write each livery entry.
 
	for (i = 0; i < LS_END; i++) {
 
		SlObject(&p->livery[i], _player_livery_desc);
 
	}
 
}
 

	
 
static void Save_PLYR(void)
saveload.c
Show inline comments
 
@@ -30,7 +30,7 @@
 
#include "variables.h"
 
#include <setjmp.h>
 

	
 
const uint16 SAVEGAME_VERSION = 33;
 
const uint16 SAVEGAME_VERSION = 34;
 
uint16 _sl_version;       /// the major savegame version identifier
 
byte   _sl_minor_version; /// the minor savegame version, DO NOT USE!
 

	
vehicle.c
Show inline comments
 
@@ -32,6 +32,7 @@
 
#include "network.h"
 
#include "yapf/yapf.h"
 
#include "date.h"
 
#include "newgrf_engine.h"
 

	
 
#define INVALID_COORD (-0x8000)
 
#define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6))
 
@@ -2301,26 +2302,100 @@ UnitID GetFreeUnitNumber(byte type)
 
	return unit;
 
}
 

	
 
static PalSpriteID GetEngineColourMap(EngineID engine_type, PlayerID player)
 
static PalSpriteID GetEngineColourMap(EngineID engine_type, PlayerID player, EngineID parent_engine_type, CargoID cargo_type)
 
{
 
	SpriteID map;
 
	byte colour = _player_colors[player];
 

	
 
	/* XXX Magic 0x307 is the first company colour remap sprite */
 
	const Player *p = GetPlayer(player);
 
	LiveryScheme scheme = LS_DEFAULT;
 

	
 
	/* The default livery is always available for use, but its in_use flag determines
 
	 * whether any _other_ liveries are in use. */
 
	if (p->livery[LS_DEFAULT].in_use) {
 
		/* Determine the livery scheme to use */
 
		switch (GetEngine(engine_type)->type) {
 
			case VEH_Train: {
 
				switch (_engine_info[engine_type].railtype) {
 
					case RAILTYPE_RAIL:
 
					case RAILTYPE_ELECTRIC:
 
					{
 
						const RailVehicleInfo *rvi = RailVehInfo(engine_type);
 

	
 
						if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
 
						if (rvi->flags & RVI_WAGON) {
 
							scheme = (cargo_type == CT_PASSENGERS || cargo_type == CT_MAIL || cargo_type == CT_VALUABLES) ?
 
								LS_PASSENGER_WAGON : LS_FREIGHT_WAGON;
 
						} else {
 
							bool is_mu = HASBIT(_engine_info[engine_type].misc_flags, EF_RAIL_IS_MU);
 

	
 
							switch (rvi->engclass) {
 
								case 0: scheme = LS_STEAM; break;
 
								case 1: scheme = is_mu ? LS_DMU : LS_DIESEL; break;
 
								case 2: scheme = is_mu ? LS_EMU : LS_ELECTRIC; break;
 
							}
 
						}
 
						break;
 
					}
 

	
 
					case RAILTYPE_MONO: scheme = LS_MONORAIL; break;
 
					case RAILTYPE_MAGLEV: scheme = LS_MAGLEV; break;
 
				}
 
				break;
 
			}
 

	
 
			case VEH_Road: {
 
				const RoadVehicleInfo *rvi = RoadVehInfo(engine_type);
 
				if (cargo_type == CT_INVALID) cargo_type = rvi->cargo_type;
 
				scheme = (cargo_type == CT_PASSENGERS) ? LS_BUS : LS_TRUCK;
 
				break;
 
			}
 

	
 
			case VEH_Ship: {
 
				const ShipVehicleInfo *svi = ShipVehInfo(engine_type);
 
				if (cargo_type == CT_INVALID) cargo_type = svi->cargo_type;
 
				scheme = (cargo_type == CT_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
 
				break;
 
			}
 

	
 
			case VEH_Aircraft: {
 
				const AircraftVehicleInfo *avi = AircraftVehInfo(engine_type);
 
				if (cargo_type == CT_INVALID) cargo_type = CT_PASSENGERS;
 
				switch (avi->subtype) {
 
					case 0: scheme = LS_HELICOPTER; break;
 
					case 1: scheme = LS_SMALL_PLANE; break;
 
					case 3: scheme = LS_LARGE_PLANE; break;
 
				}
 
				break;
 
			}
 
		}
 

	
 
		/* Switch back to the default scheme if the resolved scheme is not in use */
 
		if (!p->livery[scheme].in_use) scheme = LS_DEFAULT;
 
	}
 

	
 
	map = HASBIT(EngInfo(engine_type)->misc_flags, EF_USES_2CC) ?
 
		(SPR_2CCMAP_BASE + colour + colour * 16) : (PALETTE_RECOLOR_START + colour);
 
		(SPR_2CCMAP_BASE + p->livery[scheme].colour1 + p->livery[scheme].colour2 * 16) :
 
		(PALETTE_RECOLOR_START + p->livery[scheme].colour1);
 

	
 
	return SPRITE_PALETTE(map << PALETTE_SPRITE_START);
 
}
 

	
 
PalSpriteID GetEnginePalette(EngineID engine_type, PlayerID player)
 
{
 
	return GetEngineColourMap(engine_type, player);
 
	return GetEngineColourMap(engine_type, player, INVALID_ENGINE, CT_INVALID);
 
}
 

	
 
PalSpriteID GetVehiclePalette(const Vehicle *v)
 
{
 
	return GetEngineColourMap(v->engine_type, v->owner);
 
	if (v->type == VEH_Train) {
 
		return GetEngineColourMap(
 
			(v->u.rail.first_engine != INVALID_ENGINE && (IsArticulatedPart(v) || UsesWagonOverride(v))) ?
 
				v->u.rail.first_engine : v->engine_type,
 
			v->owner,
 
			v->u.rail.first_engine,
 
			v->cargo_type);
 
	}
 

	
 
	return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v->cargo_type);
 
}
 

	
 
// Save and load of vehicles
0 comments (0 inline, 0 general)