mirror of https://github.com/OpenTTD/OpenTTD
Feature: Custom company colours, picked from HSV colour picker.
parent
1a967aad95
commit
f8531bc64b
|
@ -35,6 +35,7 @@
|
|||
#include "smallmap_gui.h"
|
||||
#include "game/game.hpp"
|
||||
#include "goal_base.h"
|
||||
#include "spritecache.h"
|
||||
#include "story_base.h"
|
||||
#include "company_cmd.h"
|
||||
#include "timer/timer.h"
|
||||
|
@ -55,6 +56,7 @@ void UpdateObjectColours(const Company *c);
|
|||
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.
|
||||
TypedIndexContainer<std::array<Colours, MAX_COMPANIES>, CompanyID> _company_colours; ///< NOSAVE: can be determined from company structs.
|
||||
TypedIndexContainer<std::array<PaletteID, MAX_COMPANIES>, CompanyID> _company_palettes; ///< NOSAVE: can be determined from company structs.
|
||||
std::string _company_manager_face; ///< for company manager face storage in openttd.cfg
|
||||
uint _cur_company_tick_index; ///< used to generate a name for one company that doesn't have a name yet per tick
|
||||
|
||||
|
@ -163,7 +165,7 @@ TextColour GetDrawStringCompanyColour(CompanyID company)
|
|||
*/
|
||||
PaletteID GetCompanyPalette(CompanyID company)
|
||||
{
|
||||
return GetColourPalette(_company_colours[company]);
|
||||
return _company_palettes[company];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -513,7 +515,7 @@ static Colours GenerateCompanyColour()
|
|||
|
||||
/* Move the colours that look similar to each company's colour to the side */
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
Colours pcolour = c->colour;
|
||||
Colours pcolour = Colours(c->colour & 0xF);
|
||||
|
||||
for (uint i = 0; i < COLOUR_END; i++) {
|
||||
if (colours[i] == pcolour) {
|
||||
|
@ -566,6 +568,40 @@ restart:;
|
|||
}
|
||||
}
|
||||
|
||||
void ClearLivery(Livery &livery)
|
||||
{
|
||||
DeallocateDynamicSprite(livery.cached_pal_1cc);
|
||||
DeallocateDynamicSprite(livery.cached_pal_2cc);
|
||||
DeallocateDynamicSprite(livery.cached_pal_2cr);
|
||||
|
||||
livery.cached_pal_1cc = PALETTE_RECOLOUR_START + GB(livery.colour1, 0, 4);
|
||||
livery.cached_pal_2cc = SPR_2CCMAP_BASE + GB(livery.colour1, 0, 4) + GB(livery.colour2, 0, 4) * 16;
|
||||
livery.cached_pal_2cr = SPR_2CCMAP_BASE + GB(livery.colour2, 0, 4) + GB(livery.colour1, 0, 4) * 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update cached palettes for a livery.
|
||||
* @param livery Livery to update.
|
||||
* @param always_update Always update instead of clearing livery (for LS_DEFAULT which is always needed).
|
||||
*/
|
||||
void UpdateLivery(Livery &livery, bool always_update)
|
||||
{
|
||||
if ((always_update || livery.in_use != 0) && (ColoursPacker(livery.colour1).IsCustom() || ColoursPacker(livery.colour2).IsCustom())) {
|
||||
PaletteID pal_1cc = PALETTE_RECOLOUR_START + GB(livery.colour1, 0, 4);
|
||||
livery.cached_pal_1cc = CreateCompanyColourRemap(livery.colour1, livery.colour1, false, pal_1cc, livery.cached_pal_1cc);
|
||||
|
||||
if (_loaded_newgrf_features.has_2CC) {
|
||||
PaletteID pal_2cc = SPR_2CCMAP_BASE + GB(livery.colour1, 0, 4) + GB(livery.colour2, 0, 4) * 16;
|
||||
livery.cached_pal_2cc = CreateCompanyColourRemap(livery.colour1, livery.colour2, true, pal_2cc, livery.cached_pal_2cc);
|
||||
|
||||
PaletteID pal_2cr = SPR_2CCMAP_BASE + GB(livery.colour2, 0, 4) + GB(livery.colour1, 0, 4) * 16;
|
||||
livery.cached_pal_2cr = CreateCompanyColourRemap(livery.colour2, livery.colour1, true, pal_2cr, livery.cached_pal_2cr);
|
||||
}
|
||||
} else {
|
||||
ClearLivery(livery);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the livery schemes to the company's primary colour.
|
||||
* This is used on loading games without livery information and on new company start up.
|
||||
|
@ -577,6 +613,7 @@ void ResetCompanyLivery(Company *c)
|
|||
c->livery[scheme].in_use = 0;
|
||||
c->livery[scheme].colour1 = c->colour;
|
||||
c->livery[scheme].colour2 = c->colour;
|
||||
UpdateLivery(c->livery[scheme], scheme == LS_DEFAULT);
|
||||
}
|
||||
|
||||
for (Group *g : Group::Iterate()) {
|
||||
|
@ -584,8 +621,12 @@ void ResetCompanyLivery(Company *c)
|
|||
g->livery.in_use = 0;
|
||||
g->livery.colour1 = c->colour;
|
||||
g->livery.colour2 = c->colour;
|
||||
UpdateLivery(g->livery, false);
|
||||
}
|
||||
}
|
||||
|
||||
_company_colours[c->index] = c->livery[LS_DEFAULT].colour1;
|
||||
_company_palettes[c->index] = c->livery[LS_DEFAULT].cached_pal_1cc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -613,7 +654,6 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = CompanyID::Invalid(
|
|||
c->colour = colour;
|
||||
|
||||
ResetCompanyLivery(c);
|
||||
_company_colours[c->index] = c->colour;
|
||||
|
||||
/* Scale the initial loan based on the inflation rounded down to the loan interval. The maximum loan has already been inflation adjusted. */
|
||||
c->money = c->current_loan = std::min<int64_t>((INITIAL_LOAN * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL, _economy.max_loan);
|
||||
|
@ -1076,11 +1116,16 @@ CommandCost CmdSetCompanyManagerFace(DoCommandFlags flags, uint32_t bits, uint s
|
|||
*/
|
||||
void UpdateCompanyLiveries(Company *c)
|
||||
{
|
||||
UpdateLivery(c->livery[LS_DEFAULT], true);
|
||||
for (int i = 1; i < LS_END; i++) {
|
||||
if (!HasBit(c->livery[i].in_use, 0)) c->livery[i].colour1 = c->livery[LS_DEFAULT].colour1;
|
||||
if (!HasBit(c->livery[i].in_use, 1)) c->livery[i].colour2 = c->livery[LS_DEFAULT].colour2;
|
||||
UpdateLivery(c->livery[i], false);
|
||||
}
|
||||
UpdateCompanyGroupLiveries(c);
|
||||
|
||||
_company_colours[c->index] = c->livery[LS_DEFAULT].colour1;
|
||||
_company_palettes[c->index] = c->livery[LS_DEFAULT].cached_pal_1cc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1093,7 +1138,7 @@ void UpdateCompanyLiveries(Company *c)
|
|||
*/
|
||||
CommandCost CmdSetCompanyColour(DoCommandFlags flags, LiveryScheme scheme, bool primary, Colours colour)
|
||||
{
|
||||
if (scheme >= LS_END || (colour >= COLOUR_END && colour != INVALID_COLOUR)) return CMD_ERROR;
|
||||
if (scheme >= LS_END) return CMD_ERROR;
|
||||
|
||||
/* Default scheme can't be reset to invalid. */
|
||||
if (scheme == LS_DEFAULT && colour == INVALID_COLOUR) return CMD_ERROR;
|
||||
|
@ -1117,9 +1162,11 @@ CommandCost CmdSetCompanyColour(DoCommandFlags flags, LiveryScheme scheme, bool
|
|||
* original and cached company colours too. */
|
||||
if (scheme == LS_DEFAULT) {
|
||||
UpdateCompanyLiveries(c);
|
||||
_company_colours[_current_company] = colour;
|
||||
/* Update cached colour/palette for company */
|
||||
c->colour = colour;
|
||||
CompanyAdminUpdate(c);
|
||||
} else {
|
||||
UpdateLivery(c->livery[scheme], false);
|
||||
}
|
||||
} else {
|
||||
if (scheme != LS_DEFAULT) AssignBit(c->livery[scheme].in_use, 1, colour != INVALID_COLOUR);
|
||||
|
@ -1128,6 +1175,8 @@ CommandCost CmdSetCompanyColour(DoCommandFlags flags, LiveryScheme scheme, bool
|
|||
|
||||
if (scheme == LS_DEFAULT) {
|
||||
UpdateCompanyLiveries(c);
|
||||
} else {
|
||||
UpdateLivery(c->livery[scheme], false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "company_type.h"
|
||||
#include "gfx_type.h"
|
||||
#include "vehicle_type.h"
|
||||
#include "livery.h"
|
||||
|
||||
bool CheckTakeoverVehicleLimit(CompanyID cbig, CompanyID small);
|
||||
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner);
|
||||
|
@ -24,6 +25,8 @@ void CompanyAdminUpdate(const Company *company);
|
|||
void CompanyAdminBankrupt(CompanyID company_id);
|
||||
void UpdateLandscapingLimits();
|
||||
void UpdateCompanyLiveries(Company *c);
|
||||
void ClearLivery(Livery &livery);
|
||||
void UpdateLivery(Livery &livery, bool always_update);
|
||||
|
||||
Money GetAvailableMoney(CompanyID company);
|
||||
Money GetAvailableMoneyForCommand();
|
||||
|
@ -37,7 +40,9 @@ extern CompanyID _local_company;
|
|||
extern CompanyID _current_company;
|
||||
|
||||
extern TypedIndexContainer<std::array<Colours, MAX_COMPANIES>, CompanyID> _company_colours;
|
||||
extern TypedIndexContainer<std::array<PaletteID, MAX_COMPANIES>, CompanyID> _company_palettes;
|
||||
extern std::string _company_manager_face;
|
||||
|
||||
PaletteID GetCompanyPalette(CompanyID company);
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
/** @file company_gui.cpp %Company related GUIs. */
|
||||
|
||||
#include "palette_func.h"
|
||||
#include "stdafx.h"
|
||||
#include "currency.h"
|
||||
#include "error.h"
|
||||
|
@ -47,6 +48,7 @@
|
|||
#include "timer/timer.h"
|
||||
#include "timer/timer_window.h"
|
||||
#include "core/string_consumer.hpp"
|
||||
#include "blitter/factory.hpp"
|
||||
|
||||
#include "widgets/company_widget.h"
|
||||
|
||||
|
@ -584,6 +586,13 @@ static const LiveryClass _livery_class[LS_END] = {
|
|||
LC_ROAD, LC_ROAD,
|
||||
};
|
||||
|
||||
StringID GetColourString(Colours colour)
|
||||
{
|
||||
if (ColoursPacker(colour).IsCustom()) return STR_COLOUR_CUSTOM;
|
||||
if (colour == INVALID_COLOUR) return STR_COLOUR_DEFAULT;
|
||||
return STR_COLOUR_DARK_BLUE + colour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Colour selection list item, with icon and string components.
|
||||
* @tparam TSprite Recolourable sprite to draw as icon.
|
||||
|
@ -591,12 +600,372 @@ static const LiveryClass _livery_class[LS_END] = {
|
|||
template <SpriteID TSprite = SPR_SQUARE>
|
||||
class DropDownListColourItem : public DropDownIcon<DropDownString<DropDownListItem>> {
|
||||
public:
|
||||
DropDownListColourItem(int colour, bool masked) :
|
||||
DropDownIcon<DropDownString<DropDownListItem>>(TSprite, GetColourPalette(static_cast<Colours>(colour % COLOUR_END)), GetString((Colours)colour < COLOUR_END ? (STR_COLOUR_DARK_BLUE + colour) : STR_COLOUR_DEFAULT), colour, masked)
|
||||
DropDownListColourItem(PaletteID pal, StringID str, int value, bool masked) :
|
||||
DropDownIcon<DropDownString<DropDownListItem>>(TSprite, pal, GetString(str), value, masked)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class SelectCustomColourWindow : public Window {
|
||||
/* Preserved values from parent window when this window was opened. */
|
||||
uint32_t sel;
|
||||
LiveryClass lc;
|
||||
bool ctrl_pressed;
|
||||
bool primary;
|
||||
bool group;
|
||||
|
||||
Scrollbar *hue, *sat, *val, *con;
|
||||
Colours current;
|
||||
|
||||
HsvColour current_hsv;
|
||||
uint8_t contrast;
|
||||
|
||||
static inline const int BUTTON_SIZE = 10;
|
||||
static inline const int CON_MAX = UINT8_MAX;
|
||||
|
||||
void SetPresetColours()
|
||||
{
|
||||
for (uint i = 0; i < std::size(_settings_client.gui.preset_colours); ++i) {
|
||||
this->GetWidget<NWidgetCore>(WID_SCC_PRESETS + i)->colour = _settings_client.gui.preset_colours[i];
|
||||
}
|
||||
}
|
||||
|
||||
Colour AdjustBrightness(const Colour &rgb, ColourShade shade, int contrast) const
|
||||
{
|
||||
int level = (shade - SHADE_NORMAL) * contrast / (SHADE_END / 2);
|
||||
return {
|
||||
ClampTo<uint8_t>(std::max(1, rgb.r + level)),
|
||||
ClampTo<uint8_t>(std::max(1, rgb.g + level)),
|
||||
ClampTo<uint8_t>(std::max(1, rgb.b + level))
|
||||
};
|
||||
}
|
||||
|
||||
bool SetScrollbarPositions()
|
||||
{
|
||||
bool changed = false;
|
||||
changed |= this->hue->SetPosition(HsvColour::HUE_MAX - this->current_hsv.h);
|
||||
changed |= this->sat->SetPosition(this->current_hsv.s);
|
||||
changed |= this->val->SetPosition(HsvColour::VAL_MAX - this->current_hsv.v);
|
||||
changed |= this->con->SetPosition(CON_MAX - this->contrast);
|
||||
return changed;
|
||||
}
|
||||
|
||||
public:
|
||||
SelectCustomColourWindow(WindowDesc &desc, int window_number, CompanyID company, Colours colour, uint32_t sel, LiveryClass lc, bool ctrl, bool primary, bool group) :
|
||||
Window(desc), sel(sel), lc(lc), ctrl_pressed(ctrl), primary(primary), group(group)
|
||||
{
|
||||
this->InitNested(window_number);
|
||||
this->owner = (Owner)company;
|
||||
|
||||
this->current = colour;
|
||||
|
||||
ColoursPacker colourp(colour);
|
||||
if ((colourp.GetHue() | colourp.GetSaturation() | colourp.GetValue()) == 0) {
|
||||
auto [rgba, contrast] = GetCompanyColourRGB(colour);
|
||||
this->current_hsv = ConvertRgbToHsv(rgba);
|
||||
this->contrast = contrast;
|
||||
} else {
|
||||
this->current_hsv = colourp.Hsv();
|
||||
this->contrast = colourp.GetContrast();
|
||||
}
|
||||
|
||||
this->hue = this->GetScrollbar(WID_SCC_SCROLLBAR_HUE);
|
||||
this->hue->SetCapacity(HsvColour::HUE_MAX / BUTTON_SIZE);
|
||||
this->hue->SetCount(HsvColour::HUE_MAX + HsvColour::HUE_MAX / BUTTON_SIZE);
|
||||
this->sat = this->GetScrollbar(WID_SCC_SCROLLBAR_SAT);
|
||||
this->sat->SetCapacity(HsvColour::SAT_MAX / BUTTON_SIZE);
|
||||
this->sat->SetCount(HsvColour::SAT_MAX + HsvColour::SAT_MAX / BUTTON_SIZE);
|
||||
this->val = this->GetScrollbar(WID_SCC_SCROLLBAR_VAL);
|
||||
this->val->SetCapacity(HsvColour::VAL_MAX / BUTTON_SIZE);
|
||||
this->val->SetCount(HsvColour::VAL_MAX + HsvColour::VAL_MAX / BUTTON_SIZE);
|
||||
this->con = this->GetScrollbar(WID_SCC_SCROLLBAR_CON);
|
||||
this->con->SetCapacity(CON_MAX / BUTTON_SIZE);
|
||||
this->con->SetCount(CON_MAX + CON_MAX / BUTTON_SIZE);
|
||||
|
||||
this->SetScrollbarPositions();
|
||||
this->SetPresetColours();
|
||||
}
|
||||
|
||||
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SCC_CAPTION:
|
||||
return GetString(stringid, this->owner);
|
||||
|
||||
default:
|
||||
return this->Window::GetWidgetString(widget, stringid);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
HsvColour hsv = this->current_hsv;
|
||||
switch (widget) {
|
||||
case WID_SCC_HUE: {
|
||||
int range = r.Height() - 1;
|
||||
int mid = CentreBounds(r.left, r.right, 0);
|
||||
hsv.s = HsvColour::SAT_MAX;
|
||||
for (int i = 0; i <= range; i++) {
|
||||
hsv.h = HsvColour::HUE_MAX * i / range;
|
||||
hsv.v = HsvColour::VAL_MAX;
|
||||
GfxFillRect(r.left, r.bottom - i, mid - 1, r.bottom - i, ConvertHsvToRgb(hsv), FILLRECT_OPAQUE);
|
||||
hsv.v = HsvColour::VAL_MAX * 3 / 4;
|
||||
GfxFillRect(mid, r.bottom - i, r.right, r.bottom - i, ConvertHsvToRgb(hsv), FILLRECT_OPAQUE);
|
||||
}
|
||||
|
||||
/* Mark current value. */
|
||||
GfxDrawLine(r.left, r.bottom - this->current_hsv.h * range / HsvColour::HUE_MAX, r.right, r.bottom - this->current_hsv.h * range / HsvColour::HUE_MAX, PC_WHITE, 1, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_SCC_SAT: {
|
||||
int width = r.Width() - 1;
|
||||
int height = r.Height() - 1;
|
||||
|
||||
for (int x = 0; x <= width; x++) {
|
||||
hsv.s = HsvColour::SAT_MAX * x / width;
|
||||
for (int y = 0; y <= height; y++) {
|
||||
hsv.v = HsvColour::VAL_MAX * y / height;
|
||||
GfxFillRect(r.left + x, r.bottom - y, r.left + x, r.bottom - y, ConvertHsvToRgb(hsv), FILLRECT_OPAQUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark current value. */
|
||||
GfxDrawLine(r.left + this->current_hsv.s * width / HsvColour::SAT_MAX, r.top, r.left + this->current_hsv.s * width / HsvColour::SAT_MAX, r.bottom, PC_WHITE, 1, 1);
|
||||
GfxDrawLine(r.left, r.bottom - this->current_hsv.v * height / HsvColour::VAL_MAX, r.right, r.bottom - this->current_hsv.v * height / HsvColour::VAL_MAX, PC_WHITE, 1, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_SCC_CON: {
|
||||
int range = r.Height() - 1;
|
||||
int mid = CentreBounds(r.left, r.right, 0);
|
||||
Colour rgb = ConvertHsvToRgb(HsvColour{0, 0, HsvColour::VAL_MAX / 2});
|
||||
for (int i = 0; i <= range; i++) {
|
||||
int contrast = i * CON_MAX / width;
|
||||
GfxFillRect(r.left, r.bottom - i, mid - 1, r.bottom - i, AdjustBrightness(rgb, SHADE_LIGHTEST, contrast), FILLRECT_OPAQUE);
|
||||
GfxFillRect(mid, r.bottom - i, r.right, r.bottom - i, AdjustBrightness(rgb, SHADE_DARKEST, contrast), FILLRECT_OPAQUE);
|
||||
}
|
||||
|
||||
/* Mark current value. */
|
||||
GfxDrawLine(r.left, r.bottom - this->contrast * range / CON_MAX, r.right, r.bottom - this->contrast * range / CON_MAX, PC_WHITE, 1, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_SCC_OUTPUT: {
|
||||
int range = r.Height();
|
||||
/* Pack and unpack to colours, to produce the result. */
|
||||
Colours colour = this->PackColour();
|
||||
ColoursPacker colourp(colour);
|
||||
HsvColour hsv = colourp.Hsv();
|
||||
uint8_t con = colourp.GetContrast();
|
||||
for (ColourShade shade = SHADE_BEGIN; shade != SHADE_END; ++shade) {
|
||||
Colour c = ConvertHsvToRgb(AdjustHsvColourBrightness(hsv, shade, con));
|
||||
GfxFillRect(r.left, r.bottom - (shade + 1) * range / SHADE_END + 1, r.right, r.bottom - shade * range / SHADE_END, c, FILLRECT_OPAQUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (widget >= WID_SCC_DEFAULT && widget <= WID_SCC_DEFAULT_LAST && !_ctrl_pressed) {
|
||||
/* Select colour from default preset. */
|
||||
this->current = this->GetWidget<NWidgetCore>(widget)->colour;
|
||||
|
||||
auto [rgba, contrast] = GetCompanyColourRGB(this->current);
|
||||
this->current_hsv = ConvertRgbToHsv(rgba);
|
||||
this->contrast = contrast;
|
||||
|
||||
changed = this->SetScrollbarPositions();
|
||||
}
|
||||
|
||||
if (widget >= WID_SCC_PRESETS && widget <= WID_SCC_PRESETS_LAST) {
|
||||
if (_ctrl_pressed) {
|
||||
/* Save colour to preset. */
|
||||
_settings_client.gui.preset_colours[widget - WID_SCC_PRESETS] = this->PackColour();
|
||||
this->SetPresetColours();
|
||||
} else {
|
||||
/* Select colour from preset. */
|
||||
ColoursPacker cp(_settings_client.gui.preset_colours[widget - WID_SCC_PRESETS]);
|
||||
this->current_hsv = cp.Hsv();
|
||||
this->contrast = cp.GetContrast();
|
||||
|
||||
changed = this->SetScrollbarPositions();
|
||||
}
|
||||
}
|
||||
|
||||
if (widget == WID_SCC_HUE) {
|
||||
/* Click and drag on hue widget */
|
||||
const NWidgetCore *wi = this->GetWidget<NWidgetCore>(widget);
|
||||
this->current_hsv.h = std::clamp<int>(HsvColour::HUE_MAX - (pt.y - wi->pos_y) * HsvColour::HUE_MAX / (int)wi->current_y, 0, HsvColour::HUE_MAX);
|
||||
this->contrast = CON_MAX - this->con->GetPosition();
|
||||
|
||||
changed = this->SetScrollbarPositions();
|
||||
if (click_count > 0) this->mouse_capture_widget = widget;
|
||||
}
|
||||
|
||||
if (widget == WID_SCC_SAT) {
|
||||
/* Click and drag on saturation/value widget */
|
||||
const NWidgetCore *wi = this->GetWidget<NWidgetCore>(widget);
|
||||
this->current_hsv.s = std::clamp<int>((pt.x - wi->pos_x) * HsvColour::SAT_MAX / (int)wi->current_x, 0, HsvColour::SAT_MAX);
|
||||
this->current_hsv.v = std::clamp<int>(HsvColour::VAL_MAX - (pt.y - wi->pos_y) * HsvColour::VAL_MAX / (int)wi->current_y, 0, HsvColour::VAL_MAX);
|
||||
this->contrast = CON_MAX - this->con->GetPosition();
|
||||
|
||||
changed = this->SetScrollbarPositions();
|
||||
if (click_count > 0) this->mouse_capture_widget = widget;
|
||||
}
|
||||
|
||||
if (widget == WID_SCC_CON) {
|
||||
/* Click and drag on contrast widget */
|
||||
const NWidgetCore *wi = this->GetWidget<NWidgetCore>(widget);
|
||||
this->contrast = std::clamp<int>(CON_MAX - (pt.y - wi->pos_y) * CON_MAX / (int)wi->current_y, 0, CON_MAX);
|
||||
|
||||
changed = this->SetScrollbarPositions();
|
||||
if (click_count > 0) this->mouse_capture_widget = widget;
|
||||
}
|
||||
|
||||
if (!changed) return;
|
||||
|
||||
this->SetDirty();
|
||||
this->SetTimeout();
|
||||
}
|
||||
|
||||
void OnScrollbarScroll(WidgetID) override
|
||||
{
|
||||
/* Update colour from new scrollbar positions. */
|
||||
this->current_hsv.h = HsvColour::HUE_MAX - this->hue->GetPosition();
|
||||
this->current_hsv.s = this->sat->GetPosition();
|
||||
this->current_hsv.v = HsvColour::VAL_MAX - this->val->GetPosition();
|
||||
this->contrast = CON_MAX - this->con->GetPosition();
|
||||
|
||||
this->SetTimeout();
|
||||
}
|
||||
|
||||
Colours PackColour() const
|
||||
{
|
||||
Colours colour;
|
||||
ColoursPacker cp(colour);
|
||||
cp.SetIndex(this->current);
|
||||
cp.SetCustom(true);
|
||||
cp.SetHue(this->current_hsv.h);
|
||||
cp.SetSaturation(this->current_hsv.s);
|
||||
cp.SetValue(this->current_hsv.v);
|
||||
cp.SetContrast(this->contrast);
|
||||
return colour;
|
||||
}
|
||||
|
||||
void OnTimeout() override
|
||||
{
|
||||
Colours colour = this->PackColour();
|
||||
if (colour != this->current) {
|
||||
this->current = colour;
|
||||
|
||||
if (this->group) {
|
||||
Command<CMD_SET_GROUP_LIVERY>::Post((GroupID)this->sel, primary, this->current);
|
||||
} else {
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
/* Changed colour for the selected scheme, or all visible schemes if CTRL is pressed. */
|
||||
if (HasBit(this->sel, scheme) || (this->ctrl_pressed && _livery_class[scheme] == this->lc && HasBit(_loaded_newgrf_features.used_liveries, scheme))) {
|
||||
Command<CMD_SET_COMPANY_COLOUR>::Post(scheme, primary, this->current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr NWidgetPart _nested_select_custom_colour_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_CAPTION, COLOUR_GREY, WID_SCC_CAPTION), SetStringTip(STR_LIVERY_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), SetPadding(WidgetDimensions::unscaled.frametext),
|
||||
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
|
||||
NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_DARK_BLUE, WID_SCC_DEFAULT + 0), SetFill(1, 1), SetMinimalSize(16, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_PALE_GREEN, WID_SCC_DEFAULT + 1), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_PINK, WID_SCC_DEFAULT + 2), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_SCC_DEFAULT + 3), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_RED, WID_SCC_DEFAULT + 4), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_SCC_DEFAULT + 5), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_SCC_DEFAULT + 6), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_DARK_GREEN, WID_SCC_DEFAULT + 7), SetFill(1, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BLUE, WID_SCC_DEFAULT + 8), SetFill(1, 1), SetMinimalSize(16, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_CREAM, WID_SCC_DEFAULT + 9), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_SCC_DEFAULT + 10), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_PURPLE, WID_SCC_DEFAULT + 11), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SCC_DEFAULT + 12), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SCC_DEFAULT + 13), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCC_DEFAULT + 14), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_SCC_DEFAULT + 15), SetFill(1, 1),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
|
||||
NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_DARK_BLUE, WID_SCC_PRESETS + 0), SetFill(1, 1), SetMinimalSize(16, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_PALE_GREEN, WID_SCC_PRESETS + 1), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_PINK, WID_SCC_PRESETS + 2), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_SCC_PRESETS + 3), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_RED, WID_SCC_PRESETS + 4), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_SCC_PRESETS + 5), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_SCC_PRESETS + 6), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_DARK_GREEN, WID_SCC_PRESETS + 7), SetFill(1, 1),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BLUE, WID_SCC_PRESETS + 8), SetFill(1, 1), SetMinimalSize(16, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_CREAM, WID_SCC_PRESETS + 9), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_SCC_PRESETS + 10), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_PURPLE, WID_SCC_PRESETS + 11), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SCC_PRESETS + 12), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SCC_PRESETS + 13), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCC_PRESETS + 14), SetFill(1, 1),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_SCC_PRESETS + 15), SetFill(1, 1),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_INSET, COLOUR_GREY),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCC_HUE), SetMinimalSize(16, 0),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SCC_SCROLLBAR_HUE),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_INSET, COLOUR_GREY),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCC_SAT), SetMinimalSize(160, 160),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SCC_SCROLLBAR_VAL),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(NWID_HSCROLLBAR, COLOUR_GREY, WID_SCC_SCROLLBAR_SAT),
|
||||
NWidget(NWID_SPACER), SetMinimalSize(11, 11),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_INSET, COLOUR_GREY),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCC_CON), SetMinimalSize(16, 0),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SCC_SCROLLBAR_CON),
|
||||
EndContainer(),
|
||||
NWidget(WWT_INSET, COLOUR_GREY),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCC_OUTPUT), SetFill(1, 1), SetMinimalSize(16, 0),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _select_custom_colour_desc(
|
||||
WDP_AUTO, {}, 0, 0,
|
||||
WC_CUSTOM_COLOUR, WC_NONE,
|
||||
{},
|
||||
_nested_select_custom_colour_widgets
|
||||
);
|
||||
|
||||
/** Company livery colour scheme window. */
|
||||
struct SelectCompanyLiveryWindow : public Window {
|
||||
private:
|
||||
|
@ -608,57 +977,86 @@ private:
|
|||
GUIGroupList groups{};
|
||||
Scrollbar *vscroll = nullptr;
|
||||
|
||||
void ShowColourDropDownMenu(uint32_t widget)
|
||||
/**
|
||||
* Get the first selected livery.
|
||||
*/
|
||||
const Livery *GetSelectedLivery() const
|
||||
{
|
||||
uint32_t used_colours = 0;
|
||||
const Livery *livery, *default_livery = nullptr;
|
||||
bool primary = widget == WID_SCL_PRI_COL_DROPDOWN;
|
||||
uint8_t default_col = 0;
|
||||
|
||||
/* Disallow other company colours for the primary colour */
|
||||
if (this->livery_class < LC_GROUP_RAIL && HasBit(this->sel, LS_DEFAULT) && primary) {
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (c->index != _local_company) SetBit(used_colours, c->colour);
|
||||
}
|
||||
}
|
||||
|
||||
const Company *c = Company::Get(this->window_number);
|
||||
|
||||
if (this->livery_class < LC_GROUP_RAIL) {
|
||||
/* Get the first selected livery to use as the default dropdown item */
|
||||
LiveryScheme scheme;
|
||||
for (scheme = LS_BEGIN; scheme < LS_END; scheme++) {
|
||||
if (HasBit(this->sel, scheme)) break;
|
||||
}
|
||||
|
||||
if (scheme == LS_END) scheme = LS_DEFAULT;
|
||||
livery = &c->livery[scheme];
|
||||
if (scheme != LS_DEFAULT) default_livery = &c->livery[LS_DEFAULT];
|
||||
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
return &c->livery[scheme];
|
||||
} else {
|
||||
const Group *g = Group::Get(this->sel);
|
||||
return &g->livery;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default selected livery.
|
||||
*/
|
||||
const Livery *GetDefaultLivery() const
|
||||
{
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
|
||||
if (this->livery_class < LC_GROUP_RAIL) {
|
||||
if (!HasBit(this->sel, LS_DEFAULT)) return &c->livery[LS_DEFAULT];
|
||||
} else {
|
||||
const Group *g = Group::Get(this->sel);
|
||||
livery = &g->livery;
|
||||
if (g->parent == GroupID::Invalid()) {
|
||||
default_livery = &c->livery[LS_DEFAULT];
|
||||
return &c->livery[LS_DEFAULT];
|
||||
} else {
|
||||
const Group *pg = Group::Get(g->parent);
|
||||
default_livery = &pg->livery;
|
||||
return &pg->livery;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void ShowColourDropDownMenu(uint32_t widget)
|
||||
{
|
||||
uint32_t used_colours = 0;
|
||||
bool primary = widget == WID_SCL_PRI_COL_DROPDOWN;
|
||||
|
||||
/* Disallow other company colours for the primary colour */
|
||||
if (this->livery_class < LC_GROUP_RAIL && HasBit(this->sel, LS_DEFAULT) && primary) {
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (c->index != _local_company) SetBit(used_colours, c->colour & 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the first selected livery to use as the default dropdown item */
|
||||
const Livery *livery = GetSelectedLivery();
|
||||
const Livery *default_livery = GetDefaultLivery();
|
||||
|
||||
DropDownList list;
|
||||
if (default_livery != nullptr) {
|
||||
/* Add COLOUR_END to put the colour out of range, but also allow us to show what the default is */
|
||||
default_col = (primary ? default_livery->colour1 : default_livery->colour2) + COLOUR_END;
|
||||
list.push_back(std::make_unique<DropDownListColourItem<>>(default_col, false));
|
||||
list.push_back(std::make_unique<DropDownListColourItem<>>(primary ? default_livery->cached_pal_1cc : default_livery->cached_pal_2cr, STR_COLOUR_DEFAULT, INVALID_COLOUR, false));
|
||||
}
|
||||
for (Colours colour = COLOUR_BEGIN; colour != COLOUR_END; colour++) {
|
||||
list.push_back(std::make_unique<DropDownListColourItem<>>(colour, HasBit(used_colours, colour)));
|
||||
list.push_back(std::make_unique<DropDownListColourItem<>>(GetColourPalette(colour), GetColourString(colour), colour, HasBit(used_colours, colour)));
|
||||
}
|
||||
list.push_back(std::make_unique<DropDownListColourItem<>>(primary ? livery->cached_pal_1cc : livery->cached_pal_2cr, STR_COLOUR_CUSTOM, 0xFF, BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32));
|
||||
|
||||
uint8_t sel;
|
||||
int sel;
|
||||
if (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) {
|
||||
sel = primary ? livery->colour1 : livery->colour2;
|
||||
Colours col = primary ? livery->colour1 : livery->colour2;
|
||||
if (ColoursPacker(col).IsCustom()) {
|
||||
sel = 0xFF;
|
||||
} else {
|
||||
sel = ColoursPacker(col).GetIndex();
|
||||
}
|
||||
} else {
|
||||
sel = default_col;
|
||||
sel = INVALID_COLOUR;
|
||||
}
|
||||
ShowDropDownList(this, std::move(list), sel, widget);
|
||||
}
|
||||
|
@ -820,7 +1218,7 @@ public:
|
|||
if (scheme == LS_END) scheme = LS_DEFAULT;
|
||||
const Livery *livery = &c->livery[scheme];
|
||||
if (scheme == LS_DEFAULT || HasBit(livery->in_use, primary ? 0 : 1)) {
|
||||
colour = STR_COLOUR_DARK_BLUE + (primary ? livery->colour1 : livery->colour2);
|
||||
colour = GetColourString(primary ? livery->colour1 : livery->colour2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -828,7 +1226,7 @@ public:
|
|||
const Group *g = Group::Get(this->sel);
|
||||
const Livery *livery = &g->livery;
|
||||
if (HasBit(livery->in_use, primary ? 0 : 1)) {
|
||||
colour = STR_COLOUR_DARK_BLUE + (primary ? livery->colour1 : livery->colour2);
|
||||
colour = GetColourString(primary ? livery->colour1 : livery->colour2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -868,26 +1266,26 @@ public:
|
|||
|
||||
int y = ir.top;
|
||||
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
|
||||
/* Helper function to draw livery info. */
|
||||
auto draw_livery = [&](std::string_view str, const Livery &livery, bool is_selected, bool is_default_scheme, int indent) {
|
||||
/* Livery Label. */
|
||||
DrawString(sch.left + (rtl ? 0 : indent), sch.right - (rtl ? indent : 0), y + text_offs, str, is_selected ? TC_WHITE : TC_BLACK);
|
||||
|
||||
/* Text below the first dropdown. */
|
||||
DrawSprite(SPR_SQUARE, GetColourPalette(livery.colour1), pri_squ.left, y + square_offs);
|
||||
DrawString(pri.left, pri.right, y + text_offs, (is_default_scheme || HasBit(livery.in_use, 0)) ? STR_COLOUR_DARK_BLUE + livery.colour1 : STR_COLOUR_DEFAULT, is_selected ? TC_WHITE : TC_GOLD);
|
||||
DrawSprite(SPR_SQUARE, HasBit(livery.in_use, 0) ? livery.cached_pal_1cc : c->livery[LS_DEFAULT].cached_pal_1cc, pri_squ.left, y + square_offs);
|
||||
DrawString(pri.left, pri.right, y + text_offs, (is_default_scheme || HasBit(livery.in_use, 0)) ? GetColourString(livery.colour1) : STR_COLOUR_DEFAULT, is_selected ? TC_WHITE : TC_GOLD);
|
||||
|
||||
/* Text below the second dropdown. */
|
||||
if (sec.right > sec.left) { // Second dropdown has non-zero size.
|
||||
DrawSprite(SPR_SQUARE, GetColourPalette(livery.colour2), sec_squ.left, y + square_offs);
|
||||
DrawString(sec.left, sec.right, y + text_offs, (is_default_scheme || HasBit(livery.in_use, 1)) ? STR_COLOUR_DARK_BLUE + livery.colour2 : STR_COLOUR_DEFAULT, is_selected ? TC_WHITE : TC_GOLD);
|
||||
DrawSprite(SPR_SQUARE, HasBit(livery.in_use, 1) ? livery.cached_pal_2cr : c->livery[LS_DEFAULT].cached_pal_2cr, sec_squ.left, y + square_offs);
|
||||
DrawString(sec.left, sec.right, y + text_offs, (is_default_scheme || HasBit(livery.in_use, 1)) ? GetColourString(livery.colour2) : STR_COLOUR_DEFAULT, is_selected ? TC_WHITE : TC_GOLD);
|
||||
}
|
||||
|
||||
y += this->line_height;
|
||||
};
|
||||
|
||||
const Company *c = Company::Get(this->window_number);
|
||||
|
||||
if (livery_class < LC_GROUP_RAIL) {
|
||||
int pos = this->vscroll->GetPosition();
|
||||
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
|
||||
|
@ -998,6 +1396,16 @@ public:
|
|||
bool local = this->window_number == _local_company;
|
||||
if (!local) return;
|
||||
|
||||
if (index == 0xFF) {
|
||||
/* Special case for 'Custom...' option */
|
||||
int number = ((widget == WID_SCL_PRI_COL_DROPDOWN) ? 1 : 0) | (this->window_number << 1);
|
||||
if (BringWindowToFrontById(WC_CUSTOM_COLOUR, number)) return;
|
||||
|
||||
const Livery *livery = GetSelectedLivery();
|
||||
new SelectCustomColourWindow(_select_custom_colour_desc, number, (CompanyID)this->window_number, (widget == WID_SCL_PRI_COL_DROPDOWN) ? livery->colour1 : livery->colour2, this->sel, this->livery_class, _ctrl_pressed, widget == WID_SCL_PRI_COL_DROPDOWN, this->livery_class >= LC_GROUP_RAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
Colours colour = static_cast<Colours>(index);
|
||||
if (colour >= COLOUR_END) colour = INVALID_COLOUR;
|
||||
|
||||
|
@ -1114,10 +1522,10 @@ void ShowCompanyLiveryWindow(CompanyID company, GroupID group)
|
|||
/**
|
||||
* Draws the face of a company manager's face.
|
||||
* @param cmf the company manager's face
|
||||
* @param colour the (background) colour of the gradient
|
||||
* @param palette the (background) colour of the gradient
|
||||
* @param r position to draw the face
|
||||
*/
|
||||
void DrawCompanyManagerFace(const CompanyManagerFace &cmf, Colours colour, const Rect &r)
|
||||
void DrawCompanyManagerFace(const CompanyManagerFace &cmf, PaletteID palette, const Rect &r)
|
||||
{
|
||||
/* Determine offset from centre of drawing rect. */
|
||||
Dimension d = GetSpriteSize(SPR_GRADIENT);
|
||||
|
@ -1148,7 +1556,7 @@ void DrawCompanyManagerFace(const CompanyManagerFace &cmf, Colours colour, const
|
|||
}
|
||||
|
||||
/* Draw the gradient (background) */
|
||||
DrawSprite(SPR_GRADIENT, GetColourPalette(colour), x, y);
|
||||
DrawSprite(SPR_GRADIENT, palette, x, y);
|
||||
|
||||
/* Thirdly, draw sprites. */
|
||||
for (auto var : SetBitIterator(active_vars)) {
|
||||
|
@ -2105,7 +2513,7 @@ struct CompanyWindow : Window
|
|||
const Company *c = Company::Get(this->window_number);
|
||||
switch (widget) {
|
||||
case WID_C_FACE:
|
||||
DrawCompanyManagerFace(c->face, c->colour, r);
|
||||
DrawCompanyManagerFace(c->face, GetCompanyPalette(c->index), r);
|
||||
break;
|
||||
|
||||
case WID_C_FACE_TITLE:
|
||||
|
@ -2359,8 +2767,8 @@ struct BuyCompanyWindow : Window {
|
|||
{
|
||||
switch (widget) {
|
||||
case WID_BC_FACE: {
|
||||
const Company *c = Company::Get(this->window_number);
|
||||
DrawCompanyManagerFace(c->face, c->colour, r);
|
||||
const Company *c = Company::Get((CompanyID)this->window_number);
|
||||
DrawCompanyManagerFace(c->face, GetCompanyPalette(c->index), r);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -180,6 +180,6 @@ uint32_t MaskCompanyManagerFaceBits(const CompanyManagerFace &cmf, FaceVars vars
|
|||
std::string FormatCompanyManagerFaceCode(const CompanyManagerFace &cmf);
|
||||
std::optional<CompanyManagerFace> ParseCompanyManagerFaceCode(std::string_view str);
|
||||
|
||||
void DrawCompanyManagerFace(const CompanyManagerFace &cmf, Colours colour, const Rect &r);
|
||||
void DrawCompanyManagerFace(const CompanyManagerFace &cmf, PaletteID palette, const Rect &r);
|
||||
|
||||
#endif /* COMPANY_MANAGER_FACE_H */
|
||||
|
|
|
@ -1949,7 +1949,7 @@ static bool ConCompanies(std::span<std::string_view> argv)
|
|||
/* Grab the company name */
|
||||
std::string company_name = GetString(STR_COMPANY_NAME, c->index);
|
||||
|
||||
std::string colour = GetString(STR_COLOUR_DARK_BLUE + _company_colours[c->index]);
|
||||
std::string colour = GetString(STR_COLOUR_DARK_BLUE + _company_colours[c->index] & 0xF);
|
||||
IConsolePrint(CC_INFO, "#:{}({}) Company Name: '{}' Year Founded: {} Money: {} Loan: {} Value: {} (T:{}, R:{}, P:{}, S:{}) {}",
|
||||
c->index + 1, colour, company_name,
|
||||
c->inaugurated_year, (int64_t)c->money, (int64_t)c->current_loan, (int64_t)CalculateCompanyValue(c),
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "company_base.h"
|
||||
#include "company_func.h"
|
||||
#include "company_manager_face.h"
|
||||
#include "sprite.h"
|
||||
#include "strings_func.h"
|
||||
#include "zoom_func.h"
|
||||
#include "window_func.h"
|
||||
|
@ -188,7 +189,7 @@ public:
|
|||
switch (widget) {
|
||||
case WID_EM_FACE: {
|
||||
const Company *c = Company::Get(this->company);
|
||||
DrawCompanyManagerFace(c->face, c->colour, r);
|
||||
DrawCompanyManagerFace(c->face, GetCompanyPalette(c->index), r);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ struct Group : GroupPool::PoolItem<&_group_pool> {
|
|||
|
||||
Group() {}
|
||||
Group(CompanyID owner, VehicleType vehicle_type) : owner(owner), vehicle_type(vehicle_type) {}
|
||||
~Group();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "core/pool_func.hpp"
|
||||
#include "order_backup.h"
|
||||
#include "group_cmd.h"
|
||||
#include "spritecache.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
|
@ -308,6 +309,7 @@ static void PropagateChildLivery(const Group *g, bool reset_cache)
|
|||
Group *cg = Group::Get(childgroup);
|
||||
if (!HasBit(cg->livery.in_use, 0)) cg->livery.colour1 = g->livery.colour1;
|
||||
if (!HasBit(cg->livery.in_use, 1)) cg->livery.colour2 = g->livery.colour2;
|
||||
UpdateLivery(cg->livery, false);
|
||||
PropagateChildLivery(cg, reset_cache);
|
||||
}
|
||||
}
|
||||
|
@ -323,11 +325,20 @@ void UpdateCompanyGroupLiveries(const Company *c)
|
|||
if (g->owner == c->index && g->parent == GroupID::Invalid()) {
|
||||
if (!HasBit(g->livery.in_use, 0)) g->livery.colour1 = c->livery[LS_DEFAULT].colour1;
|
||||
if (!HasBit(g->livery.in_use, 1)) g->livery.colour2 = c->livery[LS_DEFAULT].colour2;
|
||||
UpdateLivery(g->livery, false);
|
||||
PropagateChildLivery(g, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Group::~Group()
|
||||
{
|
||||
if (CleaningPool()) return;
|
||||
|
||||
DeallocateDynamicSprite(this->livery.cached_pal_1cc);
|
||||
DeallocateDynamicSprite(this->livery.cached_pal_2cc);
|
||||
DeallocateDynamicSprite(this->livery.cached_pal_2cr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new vehicle group.
|
||||
|
@ -483,8 +494,9 @@ CommandCost CmdAlterGroup(DoCommandFlags flags, AlterGroupMode mode, GroupID gro
|
|||
if (!HasBit(g->livery.in_use, 0) || !HasBit(g->livery.in_use, 1)) {
|
||||
/* Update livery with new parent's colours if either colour is default. */
|
||||
const Livery *livery = GetParentLivery(g);
|
||||
if (!HasBit(g->livery.in_use, 0)) g->livery.colour1 = livery->colour1;
|
||||
if (!HasBit(g->livery.in_use, 1)) g->livery.colour2 = livery->colour2;
|
||||
if (!HasBit(g->livery.in_use, 0)) if (!HasBit(g->livery.in_use, 0)) g->livery.colour1 = livery->colour1;
|
||||
if (!HasBit(g->livery.in_use, 1)) if (!HasBit(g->livery.in_use, 1)) g->livery.colour2 = livery->colour2;
|
||||
UpdateLivery(g->livery, false);
|
||||
|
||||
PropagateChildLivery(g, true);
|
||||
MarkWholeScreenDirty();
|
||||
|
@ -680,8 +692,6 @@ CommandCost CmdSetGroupLivery(DoCommandFlags flags, GroupID group_id, bool prima
|
|||
|
||||
if (g == nullptr || g->owner != _current_company) return CMD_ERROR;
|
||||
|
||||
if (colour >= COLOUR_END && colour != INVALID_COLOUR) return CMD_ERROR;
|
||||
|
||||
if (flags.Test(DoCommandFlag::Execute)) {
|
||||
if (primary) {
|
||||
AssignBit(g->livery.in_use, 0, colour != INVALID_COLOUR);
|
||||
|
@ -692,6 +702,7 @@ CommandCost CmdSetGroupLivery(DoCommandFlags flags, GroupID group_id, bool prima
|
|||
if (colour == INVALID_COLOUR) colour = GetParentLivery(g)->colour2;
|
||||
g->livery.colour2 = colour;
|
||||
}
|
||||
UpdateLivery(g->livery, false);
|
||||
|
||||
PropagateChildLivery(g, true);
|
||||
MarkWholeScreenDirty();
|
||||
|
|
|
@ -170,6 +170,7 @@ STR_ITEMS :{COMMA}{NBSP}it
|
|||
STR_CRATES :{COMMA}{NBSP}crate{P "" s}
|
||||
|
||||
STR_COLOUR_DEFAULT :Default
|
||||
STR_COLOUR_CUSTOM :Custom...
|
||||
###length 17
|
||||
STR_COLOUR_DARK_BLUE :Dark Blue
|
||||
STR_COLOUR_PALE_GREEN :Pale Green
|
||||
|
@ -2325,6 +2326,11 @@ STR_LIVERY_LARGE_PLANE :Large Aeroplane
|
|||
STR_LIVERY_PASSENGER_TRAM :Passenger Tram
|
||||
STR_LIVERY_FREIGHT_TRAM :Freight Tram
|
||||
|
||||
STR_LIVERY_HUE :{BLACK}Hue
|
||||
STR_LIVERY_SATURATION :{BLACK}Saturation
|
||||
STR_LIVERY_LIGHTNESS :{BLACK}Lightness
|
||||
STR_LIVERY_CONTRAST :{BLACK}Contrast
|
||||
|
||||
# Face selection window
|
||||
STR_FACE_CAPTION :{WHITE}Face Selection
|
||||
STR_FACE_CANCEL_TOOLTIP :{BLACK}Cancel new face selection
|
||||
|
|
|
@ -79,6 +79,10 @@ struct Livery {
|
|||
uint8_t in_use = 0; ///< Bit 0 set if this livery should override the default livery first colour, Bit 1 for the second colour.
|
||||
Colours colour1 = COLOUR_BEGIN; ///< First colour, for all vehicles.
|
||||
Colours colour2 = COLOUR_BEGIN; ///< Second colour, for vehicles with 2CC support.
|
||||
|
||||
PaletteID cached_pal_1cc = 0; ///< NOSAVE: cached 1CC palette.
|
||||
PaletteID cached_pal_2cc = 0; ///< NOSAVE: cached 2CC palette.
|
||||
PaletteID cached_pal_2cr = 0; ///< NOSAVE: cached reversed 2CC palette.
|
||||
};
|
||||
|
||||
void ResetCompanyLivery(Company *c);
|
||||
|
|
|
@ -325,7 +325,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company
|
|||
p->Send_uint8 (c->index);
|
||||
p->Send_string(GetString(STR_COMPANY_NAME, c->index));
|
||||
p->Send_string(GetString(STR_PRESIDENT_NAME, c->index));
|
||||
p->Send_uint8 (c->colour);
|
||||
p->Send_uint8 (c->colour & 0xF);
|
||||
p->Send_bool (true);
|
||||
p->Send_uint32(c->inaugurated_year.base());
|
||||
p->Send_bool (c->is_ai);
|
||||
|
@ -348,7 +348,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Compa
|
|||
p->Send_uint8 (c->index);
|
||||
p->Send_string(GetString(STR_COMPANY_NAME, c->index));
|
||||
p->Send_string(GetString(STR_PRESIDENT_NAME, c->index));
|
||||
p->Send_uint8 (c->colour);
|
||||
p->Send_uint8 (c->colour & 0xF);
|
||||
p->Send_bool (true);
|
||||
p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
|
||||
|
||||
|
|
|
@ -1678,6 +1678,9 @@ static void AfterLoadGRFs()
|
|||
InitRailTypes();
|
||||
InitRoadTypes();
|
||||
|
||||
/* Force cached palettes to be refreshed */
|
||||
ResetVehicleColourMap();
|
||||
|
||||
for (Engine *e : Engine::IterateType(VEH_ROAD)) {
|
||||
if (_gted[e->index].rv_max_speed != 0) {
|
||||
/* Set RV maximum speed from the mph/0.8 unit value */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "water.h"
|
||||
#include "landscape.h"
|
||||
#include "company_base.h"
|
||||
#include "company_func.h"
|
||||
#include "town.h"
|
||||
#include "newgrf_animation_base.h"
|
||||
|
||||
|
@ -241,7 +242,7 @@ static uint16_t GetAirportTileCallback(CallbackID callback, uint32_t param1, uin
|
|||
return object.ResolveCallback(regs100);
|
||||
}
|
||||
|
||||
static void AirportDrawTileLayout(const TileInfo *ti, const DrawTileSpriteSpan &dts, Colours colour)
|
||||
static void AirportDrawTileLayout(const TileInfo *ti, const DrawTileSpriteSpan &dts, PaletteID cc_pal)
|
||||
{
|
||||
SpriteID image = dts.ground.sprite;
|
||||
SpriteID pal = dts.ground.pal;
|
||||
|
@ -250,11 +251,11 @@ static void AirportDrawTileLayout(const TileInfo *ti, const DrawTileSpriteSpan &
|
|||
if (image == SPR_FLAT_WATER_TILE && IsTileOnWater(ti->tile)) {
|
||||
DrawWaterClassGround(ti);
|
||||
} else {
|
||||
DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, GetColourPalette(colour)));
|
||||
DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, cc_pal));
|
||||
}
|
||||
}
|
||||
|
||||
DrawNewGRFTileSeq(ti, &dts, TO_BUILDINGS, 0, GetColourPalette(colour));
|
||||
DrawNewGRFTileSeq(ti, &dts, TO_BUILDINGS, 0, cc_pal);
|
||||
}
|
||||
|
||||
bool DrawNewAirportTile(TileInfo *ti, Station *st, const AirportTileSpec *airts)
|
||||
|
@ -278,7 +279,7 @@ bool DrawNewAirportTile(TileInfo *ti, Station *st, const AirportTileSpec *airts)
|
|||
|
||||
auto processor = group->ProcessRegisters(object, nullptr);
|
||||
auto dts = processor.GetLayout();
|
||||
AirportDrawTileLayout(ti, dts, Company::Get(st->owner)->colour);
|
||||
AirportDrawTileLayout(ti, dts, GetCompanyPalette(st->owner));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -528,7 +528,7 @@ struct NewsWindow : Window {
|
|||
|
||||
case WID_N_MGR_FACE: {
|
||||
const CompanyNewsInformation *cni = static_cast<const CompanyNewsInformation*>(this->ni->data.get());
|
||||
DrawCompanyManagerFace(cni->face, cni->colour, r);
|
||||
DrawCompanyManagerFace(cni->face, cni->colour, r); // XXX TODO this should be a palette
|
||||
GfxFillRect(r, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "landscape_type.h"
|
||||
#include "palette_func.h"
|
||||
#include "settings_type.h"
|
||||
#include "sprite.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "table/palettes.h"
|
||||
|
@ -84,6 +85,7 @@ static uint CalculateColourDistance(const Colour &col1, int r2, int g2, int b2)
|
|||
/* Palette indexes for conversion. See docs/palettes/palette_key.png */
|
||||
const uint8_t PALETTE_INDEX_CC_START = 198; ///< Palette index of start of company colour remap area.
|
||||
const uint8_t PALETTE_INDEX_CC_END = PALETTE_INDEX_CC_START + 8; ///< Palette index of end of company colour remap area.
|
||||
const uint8_t PALETTE_INDEX_CC2_START = 80; ///< Palette index of start of second company colour remap area.
|
||||
const uint8_t PALETTE_INDEX_START = 1; ///< Palette index of start of defined palette.
|
||||
const uint8_t PALETTE_INDEX_END = 215; ///< Palette index of end of defined palette.
|
||||
|
||||
|
@ -499,3 +501,43 @@ TextColour PixelColour::ToTextColour() const
|
|||
}
|
||||
return tc;
|
||||
}
|
||||
|
||||
std::pair<Colour, uint8_t> GetCompanyColourRGB(Colours colour)
|
||||
{
|
||||
static constexpr uint8_t CC_PALETTE_CONTRAST = 90;
|
||||
|
||||
PaletteID pal = GetColourPalette(colour);
|
||||
const RecolourSprite *map = GetRecolourSprite(pal);
|
||||
|
||||
Colour rgb = _palette.palette[map->palette[PALETTE_INDEX_CC_START + SHADE_NORMAL]];
|
||||
return {rgb, CC_PALETTE_CONTRAST};
|
||||
}
|
||||
|
||||
PaletteID CreateCompanyColourRemap(Colours colour1, Colours colour2, bool twocc, PaletteID basemap, PaletteID hint)
|
||||
{
|
||||
DeallocateDynamicSprite(hint);
|
||||
|
||||
PaletteID pal = AllocateDynamicSprite();
|
||||
const RecolourSprite *base = GetRecolourSprite(basemap);
|
||||
RecolourSpriteRGBA *p = new (InjectSprite(SpriteType::Recolour, pal, sizeof(RecolourSpriteRGBA)).data()) RecolourSpriteRGBA();
|
||||
|
||||
/* Copy base remap */
|
||||
p->palette = base->palette;
|
||||
std::ranges::transform(p->palette, p->rgba.begin(), [](const uint8_t &col) { return _palette.palette[col]; });
|
||||
|
||||
auto apply_colour = [](RecolourSpriteRGBA &remap, uint8_t index, Colours colour) {
|
||||
ColoursPacker cp{colour};
|
||||
if (!cp.IsCustom()) return;
|
||||
|
||||
HsvColour hsv = cp.Hsv();
|
||||
uint8_t con = cp.GetContrast();
|
||||
for (ColourShade shade = SHADE_BEGIN; shade != SHADE_END; ++shade) {
|
||||
remap.rgba[index + shade] = ConvertHsvToRgb(AdjustHsvColourBrightness(hsv, shade, con));
|
||||
}
|
||||
};
|
||||
|
||||
apply_colour(*p, PALETTE_INDEX_CC_START, colour1);
|
||||
if (twocc) apply_colour(*p, PALETTE_INDEX_CC2_START, colour2);
|
||||
|
||||
return pal;
|
||||
}
|
||||
|
|
|
@ -90,6 +90,9 @@ HsvColour AdjustHsvColourBrightness(HsvColour hsv, ColourShade shade, int contra
|
|||
PixelColour GetColourGradient(Colours colour, ColourShade shade);
|
||||
void SetColourGradient(Colours colour, ColourShade shade, PixelColour palette_colour);
|
||||
|
||||
std::pair<Colour, uint8_t> GetCompanyColourRGB(Colours colour);
|
||||
PaletteID CreateCompanyColourRemap(Colours rgb1, Colours rgb2, bool twocc, PaletteID basemap, PaletteID hint);
|
||||
|
||||
/**
|
||||
* Return the colour for a particular greyscale level.
|
||||
* @param level Intensity, 0 = black, 15 = white
|
||||
|
|
|
@ -3383,6 +3383,8 @@ bool AfterLoadGame()
|
|||
}
|
||||
|
||||
for (Company *c : Company::Iterate()) {
|
||||
UpdateLivery(c->livery[LS_DEFAULT], true);
|
||||
_company_palettes[c->index] = c->livery[LS_DEFAULT].cached_pal_1cc;
|
||||
UpdateCompanyLiveries(c);
|
||||
}
|
||||
|
||||
|
|
|
@ -210,6 +210,7 @@ struct GUISettings {
|
|||
uint8_t osk_activation; ///< Mouse gesture to trigger the OSK.
|
||||
Colours starting_colour; ///< default color scheme for the company to start a new game with
|
||||
Colours starting_colour_secondary; ///< default secondary color scheme for the company to start a new game with
|
||||
Colours preset_colours[16]; ///< custom colour presets.
|
||||
bool show_newgrf_name; ///< Show the name of the NewGRF in the build vehicle window
|
||||
bool show_cargo_in_vehicle_lists; ///< Show the cargoes the vehicles can carry in the list windows
|
||||
bool auto_remove_signals; ///< automatically remove signals when in the way during rail construction
|
||||
|
|
|
@ -185,6 +185,6 @@ inline PaletteID GroundSpritePaletteTransform(SpriteID image, PaletteID pal, Pal
|
|||
* @param colour Colour.
|
||||
* @return Recolour palette.
|
||||
*/
|
||||
static inline PaletteID GetColourPalette(Colours colour) { return PALETTE_RECOLOUR_START + colour; }
|
||||
static inline PaletteID GetColourPalette(Colours colour) { return PALETTE_RECOLOUR_START + (colour % COLOUR_END); }
|
||||
|
||||
#endif /* SPRITE_H */
|
||||
|
|
|
@ -26,6 +26,7 @@ static const SettingVariant _gui_settings_table[] = {
|
|||
};
|
||||
[templates]
|
||||
SDTC_BOOL = SDTC_BOOL( $var, SettingFlags({$flags}), $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $from, $to, $cat, $extra, $startup),
|
||||
SDTC_LIST = SDTC_LIST( $var, $type, SettingFlags({$flags}), $def, $from, $to, $cat, $extra, $startup),
|
||||
SDTC_OMANY = SDTC_OMANY( $var, $type, SettingFlags({$flags}), $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $from, $to, $cat, $extra, $startup),
|
||||
SDTC_VAR = SDTC_VAR( $var, $type, SettingFlags({$flags}), $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $str_cb, $help_cb, $val_cb, $def_cb, $range_cb, $from, $to, $cat, $extra, $startup),
|
||||
|
||||
|
@ -368,6 +369,13 @@ str = STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_SECONDARY
|
|||
strhelp = STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_SECONDARY_HELPTEXT
|
||||
strval = STR_COLOUR_SECONDARY_DARK_BLUE
|
||||
|
||||
[SDTC_LIST]
|
||||
var = gui.preset_colours
|
||||
type = SLE_UINT32
|
||||
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync
|
||||
def = """"
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDTC_BOOL]
|
||||
var = gui.auto_remove_signals
|
||||
flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync
|
||||
|
|
|
@ -2045,7 +2045,6 @@ LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_
|
|||
const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, uint8_t livery_setting)
|
||||
{
|
||||
const Company *c = Company::Get(company);
|
||||
LiveryScheme scheme = LS_DEFAULT;
|
||||
|
||||
if (livery_setting == LIT_ALL || (livery_setting == LIT_COMPANY && company == _local_company)) {
|
||||
if (v != nullptr) {
|
||||
|
@ -2063,11 +2062,12 @@ const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID
|
|||
* whether any _other_ liveries are in use. */
|
||||
if (c->livery[LS_DEFAULT].in_use != 0) {
|
||||
/* Determine the livery scheme to use */
|
||||
scheme = GetEngineLiveryScheme(engine_type, parent_engine_type, v);
|
||||
LiveryScheme scheme = GetEngineLiveryScheme(engine_type, parent_engine_type, v);
|
||||
if (c->livery[scheme].in_use != 0) return &c->livery[scheme];
|
||||
}
|
||||
}
|
||||
|
||||
return &c->livery[scheme];
|
||||
return &c->livery[LS_DEFAULT];
|
||||
}
|
||||
|
||||
|
||||
|
@ -2080,6 +2080,15 @@ static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, Eng
|
|||
|
||||
const Engine *e = Engine::Get(engine_type);
|
||||
|
||||
/* Default livery for spectators */
|
||||
static const Livery default_livery = {
|
||||
0, COLOUR_GREY, COLOUR_GREY,
|
||||
PALETTE_RECOLOUR_START, SPR_2CCMAP_BASE, SPR_2CCMAP_BASE,
|
||||
};
|
||||
|
||||
bool twocc = e->info.misc_flags.Test(EngineMiscFlag::Uses2CC);
|
||||
const Livery *livery = Company::IsValidID(company) ? GetEngineLivery(engine_type, company, parent_engine_type, v, _settings_client.gui.liveries) : &default_livery;
|
||||
|
||||
/* Check if we should use the colour map callback */
|
||||
if (e->info.callback_mask.Test(VehicleCallbackMask::ColourRemap)) {
|
||||
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
|
||||
|
@ -2090,6 +2099,15 @@ static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, Eng
|
|||
/* If bit 14 is set, then the company colours are applied to the
|
||||
* map else it's returned as-is. */
|
||||
if (!HasBit(callback, 14)) {
|
||||
/* Test if this is the standard remap/reversed remap */
|
||||
if (map == PALETTE_RECOLOUR_START + (livery->colour1 & 0xF)) {
|
||||
map = livery->cached_pal_1cc;
|
||||
} else if (map == SPR_2CCMAP_BASE + (livery->colour1 & 0xF) + (livery->colour2 & 0xF) * 16) {
|
||||
map = livery->cached_pal_2cc;
|
||||
} else if (map == SPR_2CCMAP_BASE + (livery->colour2 & 0xF) + (livery->colour1 & 0xF) * 16) {
|
||||
map = livery->cached_pal_2cr;
|
||||
}
|
||||
|
||||
/* Update cache */
|
||||
if (v != nullptr) const_cast<Vehicle *>(v)->colourmap = map;
|
||||
return map;
|
||||
|
@ -2097,17 +2115,19 @@ static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, Eng
|
|||
}
|
||||
}
|
||||
|
||||
bool twocc = e->info.misc_flags.Test(EngineMiscFlag::Uses2CC);
|
||||
|
||||
if (map == PAL_NONE) map = twocc ? (PaletteID)SPR_2CCMAP_BASE : (PaletteID)PALETTE_RECOLOUR_START;
|
||||
|
||||
/* Spectator has news shown too, but has invalid company ID - as well as dedicated server */
|
||||
if (!Company::IsValidID(company)) return map;
|
||||
|
||||
const Livery *livery = GetEngineLivery(engine_type, company, parent_engine_type, v, _settings_client.gui.liveries);
|
||||
|
||||
map += livery->colour1;
|
||||
if (twocc) map += livery->colour2 * 16;
|
||||
if (map == PALETTE_RECOLOUR_START || map == SPR_2CCMAP_BASE) {
|
||||
/* Use cached palette when using default remaps */
|
||||
map = twocc ? livery->cached_pal_2cc : livery->cached_pal_1cc;
|
||||
} else {
|
||||
/* Add offsets for custom NewGRF remaps */
|
||||
map += livery->colour1;
|
||||
if (twocc) map += livery->colour2 * 16;
|
||||
}
|
||||
|
||||
/* Update cache */
|
||||
if (v != nullptr) const_cast<Vehicle *>(v)->colourmap = map;
|
||||
|
|
|
@ -300,8 +300,6 @@ void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, Fra
|
|||
if (flags.Test(FrameFlag::Transparent)) {
|
||||
GfxFillRect(left, top, right, bottom, PALETTE_TO_TRANSPARENT, FILLRECT_RECOLOUR);
|
||||
} else {
|
||||
assert(colour < COLOUR_END);
|
||||
|
||||
const PixelColour dark = GetColourGradient(colour, SHADE_DARK);
|
||||
const PixelColour medium_dark = GetColourGradient(colour, SHADE_LIGHT);
|
||||
const PixelColour medium_light = GetColourGradient(colour, SHADE_LIGHTER);
|
||||
|
|
|
@ -75,6 +75,25 @@ enum CompanyFinancesWidgets : WidgetID {
|
|||
};
|
||||
|
||||
|
||||
/** Widgets of the #SelectCustomColourWindow class. */
|
||||
enum SelectCustomColourWidgets {
|
||||
WID_SCC_CAPTION, ///< Caption of window.
|
||||
WID_SCC_HUE,
|
||||
WID_SCC_SCROLLBAR_HUE, ///< Hue scrollbar.
|
||||
WID_SCC_SAT,
|
||||
WID_SCC_SCROLLBAR_SAT, ///< Saturation scrollbar.
|
||||
WID_SCC_VAL,
|
||||
WID_SCC_SCROLLBAR_VAL, ///< Value scrollbar.
|
||||
WID_SCC_CON,
|
||||
WID_SCC_SCROLLBAR_CON, ///< Contrast scrollbar.
|
||||
WID_SCC_OUTPUT,
|
||||
WID_SCC_DEFAULT, ///< First default colour.
|
||||
WID_SCC_DEFAULT_LAST = WID_SCC_DEFAULT + COLOUR_END - 1,
|
||||
WID_SCC_PRESETS, ///< First preset colour.
|
||||
WID_SCC_PRESETS_LAST = WID_SCC_PRESETS + COLOUR_END - 1,
|
||||
};
|
||||
|
||||
|
||||
/** Widgets of the #SelectCompanyLiveryWindow class. */
|
||||
enum SelectCompanyLiveryWidgets : WidgetID {
|
||||
WID_SCL_CAPTION, ///< Caption of window.
|
||||
|
|
|
@ -231,6 +231,12 @@ enum WindowClass : uint16_t {
|
|||
*/
|
||||
WC_COMPANY_COLOUR,
|
||||
|
||||
/**
|
||||
* Custom colour selection; %Window numbers:
|
||||
* - #CompanyID = #SelectCustomColourWidgets
|
||||
*/
|
||||
WC_CUSTOM_COLOUR,
|
||||
|
||||
/**
|
||||
* Alter company face window; %Window numbers:
|
||||
* - #CompanyID = #SelectCompanyManagerFaceWidgets
|
||||
|
|
Loading…
Reference in New Issue