# HG changeset patch # User Peter Nelson # Date 2023-12-27 15:26:33 # Node ID d8c125d1539541b1d7fd11ddfdca0f3405d4a84f # Parent 611d328c4327d80d9726b1383f27b7455ad071f9 Fix: Changing default livery did not propagate to group liveries. #11614 attempted to address this but did not handle 2CC properly, and changes to the default livery were not handled. diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -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) { - for (int i = 1; i < LS_END; i++) { - 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 (scheme == LS_DEFAULT) { - for (int i = 1; i < LS_END; i++) { - if (!HasBit(c->livery[i].in_use, 1)) c->livery[i].colour2 = colour; - } + UpdateCompanyGroupLiveries(c); } } diff --git a/src/company_func.h b/src/company_func.h --- a/src/company_func.h +++ b/src/company_func.h @@ -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); diff --git a/src/company_gui.cpp b/src/company_gui.cpp --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -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(std::min(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) { diff --git a/src/group.h b/src/group.h --- a/src/group.h +++ b/src/group.h @@ -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 */ diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -275,17 +275,20 @@ 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) { - /* Company colour data is indirectly cached. */ - for (Vehicle *v : Vehicle::Iterate()) { - if (v->group_id == g->index && (!v->IsGroundVehicle() || v->IsFrontEngine())) { - for (Vehicle *u = v; u != nullptr; u = u->Next()) { - u->colourmap = PAL_NONE; - u->InvalidateNewGRFCache(); + if (reset_cache) { + /* Company colour data is indirectly cached. */ + for (Vehicle *v : Vehicle::Iterate()) { + if (v->group_id == g->index && (!v->IsGroundVehicle() || v->IsFrontEngine())) { + for (Vehicle *u = v; u != nullptr; u = u->Next()) { + u->colourmap = PAL_NONE; + u->InvalidateNewGRFCache(); + } } } } @@ -294,11 +297,26 @@ void PropagateChildLivery(const Group *g 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. + * @param c Company to update. + */ +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; } - PropagateChildLivery(g); + PropagateChildLivery(g, true); MarkWholeScreenDirty(); } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3262,6 +3262,10 @@ bool AfterLoadGame() } } + for (Company *c : Company::Iterate()) { + UpdateCompanyLiveries(c); + } + AfterLoadLabelMaps(); AfterLoadCompanyStats(); AfterLoadStoryBook();