Changeset - r28345:d8c125d15395
[Not reviewed]
master
0 6 0
Peter Nelson - 4 months ago 2023-12-27 15:26:33
peter1138@openttd.org
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.
6 files changed with 59 insertions and 26 deletions:
0 comments (0 inline, 0 general)
src/company_cmd.cpp
Show inline comments
 
@@ -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);
 
			}
 
		}
 

	
src/company_func.h
Show inline comments
 
@@ -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);
src/company_gui.cpp
Show inline comments
 
@@ -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) {
src/group.h
Show inline comments
 
@@ -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 */
src/group_cmd.cpp
Show inline comments
 
@@ -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();
 
	}
 

	
src/saveload/afterload.cpp
Show inline comments
 
@@ -3262,6 +3262,10 @@ bool AfterLoadGame()
 
		}
 
	}
 

	
 
	for (Company *c : Company::Iterate()) {
 
		UpdateCompanyLiveries(c);
 
	}
 

	
 
	AfterLoadLabelMaps();
 
	AfterLoadCompanyStats();
 
	AfterLoadStoryBook();
0 comments (0 inline, 0 general)