1
0
Fork 0

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.
pull/11638/head
Peter Nelson 2023-12-27 15:26:33 +00:00 committed by Peter Nelson
parent 3b18877b87
commit bfb4254226
6 changed files with 59 additions and 26 deletions

View File

@ -949,6 +949,20 @@ CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, CompanyManagerFace cmf
return CommandCost(); return CommandCost();
} }
/**
* 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 * Change the company's company-colour
* @param flags operation to perform * @param flags operation to perform
@ -982,9 +996,7 @@ CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool p
/* If setting the first colour of the default scheme, adjust the /* If setting the first colour of the default scheme, adjust the
* original and cached company colours too. */ * original and cached company colours too. */
if (scheme == LS_DEFAULT) { if (scheme == LS_DEFAULT) {
for (int i = 1; i < LS_END; i++) { UpdateCompanyLiveries(c);
if (!HasBit(c->livery[i].in_use, 0)) c->livery[i].colour1 = colour;
}
_company_colours[_current_company] = colour; _company_colours[_current_company] = colour;
c->colour = colour; c->colour = colour;
CompanyAdminUpdate(c); CompanyAdminUpdate(c);
@ -995,9 +1007,7 @@ CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool p
c->livery[scheme].colour2 = colour; c->livery[scheme].colour2 = colour;
if (scheme == LS_DEFAULT) { if (scheme == LS_DEFAULT) {
for (int i = 1; i < LS_END; i++) { UpdateCompanyGroupLiveries(c);
if (!HasBit(c->livery[i].in_use, 1)) c->livery[i].colour2 = colour;
}
} }
} }

View File

@ -24,6 +24,7 @@ void ShowBuyCompanyDialog(CompanyID company, bool hostile_takeover);
void CompanyAdminUpdate(const Company *company); void CompanyAdminUpdate(const Company *company);
void CompanyAdminBankrupt(CompanyID company_id); void CompanyAdminBankrupt(CompanyID company_id);
void UpdateLandscapingLimits(); void UpdateLandscapingLimits();
void UpdateCompanyLiveries(Company *c);
bool CheckCompanyHasMoney(CommandCost &cost); bool CheckCompanyHasMoney(CommandCost &cost);
void SubtractMoneyFromCompany(const CommandCost& cost); void SubtractMoneyFromCompany(const CommandCost& cost);

View File

@ -907,18 +907,18 @@ public:
int y = ir.top; int y = ir.top;
/* Helper function to draw livery info. */ /* 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. */ /* 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. */ /* Text below the first dropdown. */
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour1), pri_squ.left, y + square_offs); DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(livery.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); 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. */ /* Text below the second dropdown. */
if (sec.right > sec.left) { // Second dropdown has non-zero size. 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); DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(livery.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); 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; 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())); 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) { for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
const Group *g = this->groups[i]; const Group *g = this->groups[i];
const bool livery_set = HasBit(g->livery.in_use, 0);
SetDParam(0, g->index); 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) { if (this->vscroll->GetCount() == 0) {

View File

@ -112,5 +112,6 @@ void SetTrainGroupID(Train *v, GroupID grp);
void UpdateTrainGroupID(Train *v); void UpdateTrainGroupID(Train *v);
void RemoveAllGroupsForCompany(const CompanyID company); void RemoveAllGroupsForCompany(const CompanyID company);
bool GroupIsInGroup(GroupID search, GroupID group); bool GroupIsInGroup(GroupID search, GroupID group);
void UpdateCompanyGroupLiveries(const Company *c);
#endif /* GROUP_H */ #endif /* GROUP_H */

View File

@ -275,17 +275,20 @@ const Livery *GetParentLivery(const Group *g)
/** /**
* Propagate a livery change to a group's children. * Propagate a livery change to a group's children, and optionally update cached vehicle colourmaps.
* @param g Group. * @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. */ if (reset_cache) {
for (Vehicle *v : Vehicle::Iterate()) { /* Company colour data is indirectly cached. */
if (v->group_id == g->index && (!v->IsGroundVehicle() || v->IsFrontEngine())) { for (Vehicle *v : Vehicle::Iterate()) {
for (Vehicle *u = v; u != nullptr; u = u->Next()) { if (v->group_id == g->index && (!v->IsGroundVehicle() || v->IsFrontEngine())) {
u->colourmap = PAL_NONE; for (Vehicle *u = v; u != nullptr; u = u->Next()) {
u->InvalidateNewGRFCache(); u->colourmap = PAL_NONE;
u->InvalidateNewGRFCache();
}
} }
} }
} }
@ -294,11 +297,26 @@ void PropagateChildLivery(const Group *g)
if (cg->parent == g->index) { if (cg->parent == g->index) {
if (!HasBit(cg->livery.in_use, 0)) cg->livery.colour1 = g->livery.colour1; 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; 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) Group::Group(Owner owner)
{ {
@ -453,7 +471,7 @@ CommandCost CmdAlterGroup(DoCommandFlag flags, AlterGroupMode mode, GroupID grou
g->livery.colour1 = livery->colour1; g->livery.colour1 = livery->colour1;
g->livery.colour2 = livery->colour2; g->livery.colour2 = livery->colour2;
PropagateChildLivery(g); PropagateChildLivery(g, true);
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} }
} }
@ -661,7 +679,7 @@ CommandCost CmdSetGroupLivery(DoCommandFlag flags, GroupID group_id, bool primar
g->livery.colour2 = colour; g->livery.colour2 = colour;
} }
PropagateChildLivery(g); PropagateChildLivery(g, true);
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} }

View File

@ -3262,6 +3262,10 @@ bool AfterLoadGame()
} }
} }
for (Company *c : Company::Iterate()) {
UpdateCompanyLiveries(c);
}
AfterLoadLabelMaps(); AfterLoadLabelMaps();
AfterLoadCompanyStats(); AfterLoadCompanyStats();
AfterLoadStoryBook(); AfterLoadStoryBook();