@@ -950,6 +950,20 @@ CommandCost CmdSetCompanyManagerFace(DoC
}
/**
* Update liveries for a company. This is called when the LS_DEFAULT scheme is changed, to update schemes with colours
* set to default.
* @param c Company to update.
*/
void UpdateCompanyLiveries(Company *c)
{
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;
UpdateCompanyGroupLiveries(c);
* Change the company's company-colour
* @param flags operation to perform
* @param scheme scheme to set
@@ -982,9 +996,7 @@ CommandCost CmdSetCompanyColour(DoComman
/* If setting the first colour of the default scheme, adjust the
* original and cached company colours too. */
if (scheme == LS_DEFAULT) {
if (!HasBit(c->livery[i].in_use, 0)) c->livery[i].colour1 = colour;
UpdateCompanyLiveries(c);
_company_colours[_current_company] = colour;
c->colour = colour;
CompanyAdminUpdate(c);
@@ -995,9 +1007,7 @@ CommandCost CmdSetCompanyColour(DoComman
c->livery[scheme].colour2 = colour;
if (!HasBit(c->livery[i].in_use, 1)) c->livery[i].colour2 = colour;
@@ -24,6 +24,7 @@ void ShowBuyCompanyDialog(CompanyID comp
void CompanyAdminUpdate(const Company *company);
void CompanyAdminBankrupt(CompanyID company_id);
void UpdateLandscapingLimits();
void UpdateCompanyLiveries(Company *c);
bool CheckCompanyHasMoney(CommandCost &cost);
void SubtractMoneyFromCompany(const CommandCost& cost);
@@ -907,18 +907,18 @@ public:
int y = ir.top;
/* Helper function to draw livery info. */
auto draw_livery = [&](StringID str, const Livery &liv, bool sel, bool def, int indent) {
auto draw_livery = [&](StringID 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, sel ? TC_WHITE : TC_BLACK);
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, GENERAL_SPRITE_COLOUR(liv.colour1), pri_squ.left, y + square_offs);
DrawString(pri.left, pri.right, y + text_offs, (def || HasBit(liv.in_use, 0)) ? STR_COLOUR_DARK_BLUE + liv.colour1 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD);
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(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);
/* Text below the second dropdown. */
if (sec.right > sec.left) { // Second dropdown has non-zero size.
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour2), sec_squ.left, y + square_offs);
DrawString(sec.left, sec.right, y + text_offs, (def || HasBit(liv.in_use, 1)) ? STR_COLOUR_DARK_BLUE + liv.colour2 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD);
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(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);
y += this->line_height;
@@ -938,9 +938,8 @@ public:
uint max = static_cast<uint>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->groups.size()));
for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
const Group *g = this->groups[i];
const bool livery_set = HasBit(g->livery.in_use, 0);
SetDParam(0, g->index);
draw_livery(STR_GROUP_NAME, livery_set ? g->livery : c->livery[LS_DEFAULT], this->sel == g->index, livery_set, this->indents[i] * WidgetDimensions::scaled.hsep_indent);
draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, this->indents[i] * WidgetDimensions::scaled.hsep_indent);
if (this->vscroll->GetCount() == 0) {
@@ -112,5 +112,6 @@ void SetTrainGroupID(Train *v, GroupID g
void UpdateTrainGroupID(Train *v);
void RemoveAllGroupsForCompany(const CompanyID company);
bool GroupIsInGroup(GroupID search, GroupID group);
void UpdateCompanyGroupLiveries(const Company *c);
#endif /* GROUP_H */
@@ -275,11 +275,13 @@ const Livery *GetParentLivery(const Grou
* Propagate a livery change to a group's children.
* @param g Group.
* Propagate a livery change to a group's children, and optionally update cached vehicle colourmaps.
* @param g Group to propagate colours to children.
* @param reset_cache Reset colourmap of vehicles in this group.
void PropagateChildLivery(const Group *g)
static void PropagateChildLivery(const Group *g, bool reset_cache)
if (reset_cache) {
/* Company colour data is indirectly cached. */
for (Vehicle *v : Vehicle::Iterate()) {
if (v->group_id == g->index && (!v->IsGroundVehicle() || v->IsFrontEngine())) {
@@ -289,16 +291,32 @@ void PropagateChildLivery(const Group *g
for (Group *cg : Group::Iterate()) {
if (cg->parent == g->index) {
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;
PropagateChildLivery(cg);
PropagateChildLivery(cg, reset_cache);
* Update group liveries for a company. This is called when the LS_DEFAULT scheme is changed, to update groups with
* colours set to default.
void UpdateCompanyGroupLiveries(const Company *c)
for (Group *g : Group::Iterate()) {
if (g->owner == c->index && g->parent == INVALID_GROUP) {
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;
PropagateChildLivery(g, false);
Group::Group(Owner owner)
@@ -453,7 +471,7 @@ CommandCost CmdAlterGroup(DoCommandFlag
g->livery.colour1 = livery->colour1;
g->livery.colour2 = livery->colour2;
PropagateChildLivery(g);
PropagateChildLivery(g, true);
MarkWholeScreenDirty();
@@ -661,7 +679,7 @@ CommandCost CmdSetGroupLivery(DoCommandF
g->livery.colour2 = colour;
@@ -3262,6 +3262,10 @@ bool AfterLoadGame()
for (Company *c : Company::Iterate()) {
AfterLoadLabelMaps();
AfterLoadCompanyStats();
AfterLoadStoryBook();
Status change: