Changeset - r28345:d8c125d15395
[Not reviewed]
master
0 6 0
Peter Nelson - 11 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
 
@@ -929,96 +929,106 @@ CommandCost CmdCompanyCtrl(DoCommandFlag
 
	InvalidateWindowClassesData(WC_SCRIPT_SETTINGS);
 
	InvalidateWindowClassesData(WC_SCRIPT_LIST);
 

	
 
	return CommandCost();
 
}
 

	
 
/**
 
 * Change the company manager's face.
 
 * @param flags operation to perform
 
 * @param cmf face bitmasked
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, CompanyManagerFace cmf)
 
{
 
	if (!IsValidCompanyManagerFace(cmf)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		Company::Get(_current_company)->face = cmf;
 
		MarkWholeScreenDirty();
 
	}
 
	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
 
 * @param flags operation to perform
 
 * @param scheme scheme to set
 
 * @param primary set first/second colour
 
 * @param colour new colour for vehicles, property, etc.
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool primary, Colours colour)
 
{
 
	if (scheme >= LS_END || (colour >= COLOUR_END && colour != INVALID_COLOUR)) return CMD_ERROR;
 

	
 
	/* Default scheme can't be reset to invalid. */
 
	if (scheme == LS_DEFAULT && colour == INVALID_COLOUR) return CMD_ERROR;
 

	
 
	Company *c = Company::Get(_current_company);
 

	
 
	/* Ensure no two companies have the same primary colour */
 
	if (scheme == LS_DEFAULT && primary) {
 
		for (const Company *cc : Company::Iterate()) {
 
			if (cc != c && cc->colour == colour) return CMD_ERROR;
 
		}
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		if (primary) {
 
			if (scheme != LS_DEFAULT) SB(c->livery[scheme].in_use, 0, 1, colour != INVALID_COLOUR);
 
			if (colour == INVALID_COLOUR) colour = (Colours)c->livery[LS_DEFAULT].colour1;
 
			c->livery[scheme].colour1 = colour;
 

	
 
			/* 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);
 
			}
 
		} else {
 
			if (scheme != LS_DEFAULT) SB(c->livery[scheme].in_use, 1, 1, colour != INVALID_COLOUR);
 
			if (colour == INVALID_COLOUR) colour = (Colours)c->livery[LS_DEFAULT].colour2;
 
			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);
 
			}
 
		}
 

	
 
		if (c->livery[scheme].in_use != 0) {
 
			/* If enabling a scheme, set the default scheme to be in use too */
 
			c->livery[LS_DEFAULT].in_use = 1;
 
		} else {
 
			/* Else loop through all schemes to see if any are left enabled.
 
			 * If not, disable the default scheme too. */
 
			c->livery[LS_DEFAULT].in_use = 0;
 
			for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
 
				if (c->livery[scheme].in_use != 0) {
 
					c->livery[LS_DEFAULT].in_use = 1;
 
					break;
 
				}
 
			}
 
		}
 

	
 
		ResetVehicleColourMap();
 
		MarkWholeScreenDirty();
 

	
 
		/* All graph related to companies use the company colour. */
 
		InvalidateWindowData(WC_INCOME_GRAPH, 0);
 
		InvalidateWindowData(WC_OPERATING_PROFIT, 0);
src/company_func.h
Show inline comments
 
@@ -3,48 +3,49 @@
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file company_func.h Functions related to companies. */
 

	
 
#ifndef COMPANY_FUNC_H
 
#define COMPANY_FUNC_H
 

	
 
#include "command_type.h"
 
#include "company_type.h"
 
#include "gfx_type.h"
 
#include "vehicle_type.h"
 

	
 
bool MayCompanyTakeOver(CompanyID cbig, CompanyID small);
 
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner);
 
static const int OWNED_BY_OWNER_IN_PARAMETERS_OFFSET = 2; ///< The index in the parameters for the owner information.
 
void SetDParamsForOwnedBy(Owner owner, TileIndex tile);
 
void SetLocalCompany(CompanyID new_company);
 
void ShowBuyCompanyDialog(CompanyID company, bool hostile_takeover);
 
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);
 
void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost& cost);
 
CommandCost CheckOwnership(Owner owner, TileIndex tile = 0U);
 
CommandCost CheckTileOwnership(TileIndex tile);
 

	
 
extern CompanyID _local_company;
 
extern CompanyID _current_company;
 

	
 
extern Colours _company_colours[MAX_COMPANIES];
 
extern CompanyManagerFace _company_manager_face;
 

	
 
/**
 
 * Is the current company the local company?
 
 * @return \c true of the current company is the local company, \c false otherwise.
 
 */
 
static inline bool IsLocalCompany()
 
{
 
	return _local_company == _current_company;
 
}
 

	
 
/**
 
 * Is the user representing \a company?
src/company_gui.cpp
Show inline comments
 
@@ -886,82 +886,81 @@ public:
 

	
 
		/* Coordinates of scheme name column. */
 
		const NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_SCL_SPACER_DROPDOWN);
 
		Rect sch = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
 
		/* Coordinates of first dropdown. */
 
		nwi = this->GetWidget<NWidgetBase>(WID_SCL_PRI_COL_DROPDOWN);
 
		Rect pri = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
 
		/* Coordinates of second dropdown. */
 
		nwi = this->GetWidget<NWidgetBase>(WID_SCL_SEC_COL_DROPDOWN);
 
		Rect sec = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
 

	
 
		Rect pri_squ = pri.WithWidth(this->square.width, rtl);
 
		Rect sec_squ = sec.WithWidth(this->square.width, rtl);
 

	
 
		pri = pri.Indent(this->square.width + WidgetDimensions::scaled.hsep_normal, rtl);
 
		sec = sec.Indent(this->square.width + WidgetDimensions::scaled.hsep_normal, rtl);
 

	
 
		Rect ir = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix);
 
		int square_offs = (ir.Height() - this->square.height) / 2;
 
		int text_offs   = (ir.Height() - GetCharacterHeight(FS_NORMAL)) / 2;
 

	
 
		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;
 
		};
 

	
 
		const Company *c = Company::Get((CompanyID)this->window_number);
 

	
 
		if (livery_class < LC_GROUP_RAIL) {
 
			int pos = this->vscroll->GetPosition();
 
			for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
 
				if (_livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme)) {
 
					if (pos-- > 0) continue;
 
					draw_livery(STR_LIVERY_DEFAULT + scheme, c->livery[scheme], HasBit(this->sel, scheme), scheme == LS_DEFAULT, 0);
 
				}
 
			}
 
		} else {
 
			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) {
 
				const StringID empty_labels[] = { STR_LIVERY_TRAIN_GROUP_EMPTY, STR_LIVERY_ROAD_VEHICLE_GROUP_EMPTY, STR_LIVERY_SHIP_GROUP_EMPTY, STR_LIVERY_AIRCRAFT_GROUP_EMPTY };
 
				VehicleType vtype = (VehicleType)(this->livery_class - LC_GROUP_RAIL);
 
				DrawString(ir.left, ir.right, y + text_offs, empty_labels[vtype], TC_BLACK);
 
			}
 
		}
 
	}
 

	
 
	void OnClick([[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count) override
 
	{
 
		switch (widget) {
 
			/* Livery Class buttons */
 
			case WID_SCL_CLASS_GENERAL:
 
			case WID_SCL_CLASS_RAIL:
 
			case WID_SCL_CLASS_ROAD:
 
			case WID_SCL_CLASS_SHIP:
 
			case WID_SCL_CLASS_AIRCRAFT:
 
			case WID_SCL_GROUPS_RAIL:
 
			case WID_SCL_GROUPS_ROAD:
 
			case WID_SCL_GROUPS_SHIP:
 
			case WID_SCL_GROUPS_AIRCRAFT:
 
				this->RaiseWidget(this->livery_class + WID_SCL_CLASS_GENERAL);
src/group.h
Show inline comments
 
@@ -91,26 +91,27 @@ static inline bool IsDefaultGroupID(Grou
 
{
 
	return index == DEFAULT_GROUP;
 
}
 

	
 
/**
 
 * Checks if a GroupID stands for all vehicles of a company
 
 * @param id_g The GroupID to check
 
 * @return true is id_g is identical to ALL_GROUP
 
 */
 
static inline bool IsAllGroupID(GroupID id_g)
 
{
 
	return id_g == ALL_GROUP;
 
}
 

	
 

	
 
uint GetGroupNumEngines(CompanyID company, GroupID id_g, EngineID id_e);
 
uint GetGroupNumVehicle(CompanyID company, GroupID id_g, VehicleType type);
 
uint GetGroupNumVehicleMinAge(CompanyID company, GroupID id_g, VehicleType type);
 
Money GetGroupProfitLastYearMinAge(CompanyID company, GroupID id_g, VehicleType type);
 

	
 
void SetTrainGroupID(Train *v, GroupID grp);
 
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
 
@@ -254,72 +254,90 @@ static inline void UpdateNumEngineGroup(
 
{
 
	if (old_g != new_g) {
 
		/* Decrease the num engines in the old group */
 
		GroupStatistics::Get(v->owner, old_g, v->type).num_engines[v->engine_type]--;
 

	
 
		/* Increase the num engines in the new group */
 
		GroupStatistics::Get(v->owner, new_g, v->type).num_engines[v->engine_type]++;
 
	}
 
}
 

	
 

	
 
const Livery *GetParentLivery(const Group *g)
 
{
 
	if (g->parent == INVALID_GROUP) {
 
		const Company *c = Company::Get(g->owner);
 
		return &c->livery[LS_DEFAULT];
 
	}
 

	
 
	const Group *pg = Group::Get(g->parent);
 
	return &pg->livery;
 
}
 

	
 

	
 
/**
 
 * 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();
 
				}
 
			}
 
		}
 
	}
 

	
 
	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.
 
 * @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)
 
{
 
	this->owner = owner;
 
	this->folded = false;
 
}
 

	
 

	
 
/**
 
 * Create a new vehicle group.
 
 * @param flags type of operation
 
 * @param vt vehicle type
 
 * @param parent_group parent groupid
 
 * @return the cost of this operation or an error
 
 */
 
std::tuple<CommandCost, GroupID> CmdCreateGroup(DoCommandFlag flags, VehicleType vt, GroupID parent_group)
 
{
 
	if (!IsCompanyBuildableVehicleType(vt)) return { CMD_ERROR, INVALID_GROUP };
 

	
 
	if (!Group::CanAllocateItem()) return { CMD_ERROR, INVALID_GROUP };
 

	
 
	const Group *pg = Group::GetIfValid(parent_group);
 
	if (pg != nullptr) {
 
		if (pg->owner != _current_company) return { CMD_ERROR, INVALID_GROUP };
 
@@ -432,49 +450,49 @@ CommandCost CmdAlterGroup(DoCommandFlag 
 
			}
 
		}
 
	} else if (mode == AlterGroupMode::SetParent) {
 
		/* Set group parent */
 
		const Group *pg = Group::GetIfValid(parent_id);
 

	
 
		if (pg != nullptr) {
 
			if (pg->owner != _current_company) return CMD_ERROR;
 
			if (pg->vehicle_type != g->vehicle_type) return CMD_ERROR;
 

	
 
			/* Ensure request parent isn't child of group.
 
			 * This is the only place that infinite loops are prevented. */
 
			if (GroupIsInGroup(pg->index, g->index)) return_cmd_error(STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION);
 
		}
 

	
 
		if (flags & DC_EXEC) {
 
			g->parent = (pg == nullptr) ? INVALID_GROUP : pg->index;
 
			GroupStatistics::UpdateAutoreplace(g->owner);
 

	
 
			if (g->livery.in_use == 0) {
 
				const Livery *livery = GetParentLivery(g);
 
				g->livery.colour1 = livery->colour1;
 
				g->livery.colour2 = livery->colour2;
 

	
 
				PropagateChildLivery(g);
 
				PropagateChildLivery(g, true);
 
				MarkWholeScreenDirty();
 
			}
 
		}
 
	} else {
 
		return CMD_ERROR;
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		InvalidateWindowData(WC_REPLACE_VEHICLE, g->vehicle_type, 1);
 
		InvalidateWindowData(GetWindowClassForVehicleType(g->vehicle_type), VehicleListIdentifier(VL_GROUP_LIST, g->vehicle_type, _current_company).Pack());
 
		InvalidateWindowData(WC_COMPANY_COLOUR, g->owner, g->vehicle_type);
 
		InvalidateWindowClassesData(WC_VEHICLE_VIEW);
 
		InvalidateWindowClassesData(WC_VEHICLE_DETAILS);
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 

	
 
/**
 
 * Do add a vehicle to a group.
 
 * @param v Vehicle to add.
 
 * @param new_g Group to add to.
 
 */
 
@@ -640,49 +658,49 @@ CommandCost CmdRemoveAllVehiclesGroup(Do
 
 * @param flags     Command flags.
 
 * @param group_id Group ID.
 
 * @param primary Set primary instead of secondary colour
 
 * @param colour Colour.
 
 */
 
CommandCost CmdSetGroupLivery(DoCommandFlag flags, GroupID group_id, bool primary, Colours colour)
 
{
 
	Group *g = Group::GetIfValid(group_id);
 

	
 
	if (g == nullptr || g->owner != _current_company) return CMD_ERROR;
 

	
 
	if (colour >= COLOUR_END && colour != INVALID_COLOUR) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		if (primary) {
 
			SB(g->livery.in_use, 0, 1, colour != INVALID_COLOUR);
 
			if (colour == INVALID_COLOUR) colour = (Colours)GetParentLivery(g)->colour1;
 
			g->livery.colour1 = colour;
 
		} else {
 
			SB(g->livery.in_use, 1, 1, colour != INVALID_COLOUR);
 
			if (colour == INVALID_COLOUR) colour = (Colours)GetParentLivery(g)->colour2;
 
			g->livery.colour2 = colour;
 
		}
 

	
 
		PropagateChildLivery(g);
 
		PropagateChildLivery(g, true);
 
		MarkWholeScreenDirty();
 
	}
 

	
 
	return CommandCost();
 
}
 

	
 
/**
 
 * Set group flag for a group and its sub-groups.
 
 * @param g initial group.
 
 * @param set 1 to set or 0 to clear protection.
 
 */
 
static void SetGroupFlag(Group *g, GroupFlags flag, bool set, bool children)
 
{
 
	if (set) {
 
		SetBit(g->flags, flag);
 
	} else {
 
		ClrBit(g->flags, flag);
 
	}
 

	
 
	if (!children) return;
 

	
 
	for (Group *pg : Group::Iterate()) {
 
		if (pg->parent == g->index) SetGroupFlag(pg, flag, set, true);
 
	}
src/saveload/afterload.cpp
Show inline comments
 
@@ -3241,48 +3241,52 @@ bool AfterLoadGame()
 
		for (Station *st : Station::Iterate()) UpdateStationAcceptance(st, false);
 
	}
 

	
 
	if (IsSavegameVersionBefore(SLV_SAVEGAME_ID)) {
 
		GenerateSavegameId();
 
	}
 

	
 
	if (IsSavegameVersionBefore(SLV_AI_START_DATE)) {
 
		/* For older savegames, we don't now the actual interval; so set it to the newgame value. */
 
		_settings_game.difficulty.competitors_interval = _settings_newgame.difficulty.competitors_interval;
 

	
 
		/* We did load the "period" of the timer, but not the fired/elapsed. We can deduce that here. */
 
		extern TimeoutTimer<TimerGameTick> _new_competitor_timeout;
 
		_new_competitor_timeout.storage.elapsed = 0;
 
		_new_competitor_timeout.fired = _new_competitor_timeout.period == 0;
 
	}
 

	
 
	if (IsSavegameVersionBefore(SLV_NEWGRF_LAST_SERVICE)) {
 
		/* Set service date provided to NewGRF. */
 
		for (Vehicle *v : Vehicle::Iterate()) {
 
			v->date_of_last_service_newgrf = v->date_of_last_service;
 
		}
 
	}
 

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

	
 
	AfterLoadLabelMaps();
 
	AfterLoadCompanyStats();
 
	AfterLoadStoryBook();
 

	
 
	_gamelog.PrintDebug(1);
 

	
 
	InitializeWindowsAndCaches();
 
	/* Restore the signals */
 
	ResetSignalHandlers();
 

	
 
	AfterLoadLinkGraphs();
 

	
 
	CheckGroundVehiclesAtCorrectZ();
 

	
 
	/* Start the scripts. This MUST happen after everything else except
 
	 * starting a new company. */
 
	StartScripts();
 

	
 
	/* If Load Scenario / New (Scenario) Game is used,
 
	 *  a company does not exist yet. So create one here.
 
	 * 1 exception: network-games. Those can have 0 companies
 
	 *   But this exception is not true for non-dedicated network servers! */
 
	if (!_networking || (_networking && _network_server && !_network_dedicated)) {
 
		CompanyID first_human_company = GetFirstPlayableCompanyID();
0 comments (0 inline, 0 general)