Changeset - r17095:192110abe258
[Not reviewed]
master
0 6 0
rubidium - 14 years ago 2011-01-18 21:30:59
rubidium@openttd.org
(svn r21842) -Feature [FS#4393]: [NewGRF] Introduction dates/required types for rail types; e.g. introduce a particular rail type in 1960 (or when a vehicle using it is introduced), but also allow limiting its introduction to only happen when the required railtypes are available
6 files changed with 135 insertions and 3 deletions:
0 comments (0 inline, 0 general)
src/engine.cpp
Show inline comments
 
@@ -44,6 +44,11 @@ EngineOverrideManager _engine_mngr;
 
 */
 
static Year _year_engine_aging_stops;
 

	
 
/**
 
 * The railtypes that have been or never will be introduced, or
 
 * an inverse bitmap of rail types that have to be introduced. */
 
static uint16 _introduced_railtypes;
 

	
 
/** Number of engines of each vehicle type in original engine data */
 
const uint8 _engine_counts[4] = {
 
	lengthof(_orig_rail_vehicle_info),
 
@@ -474,8 +479,30 @@ void SetupEngines()
 
		const Engine *e = new Engine(eid->type, eid->internal_id);
 
		assert(e->index == index);
 
	}
 

	
 
	_introduced_railtypes = 0;
 
}
 

	
 
/**
 
 * Check whether the railtypes should be introduced.
 
 */
 
static void CheckRailIntroduction()
 
{
 
	/* All railtypes have been introduced. */
 
	if (_introduced_railtypes == UINT16_MAX || Company::GetPoolSize() == 0) return;
 

	
 
	/* We need to find the railtypes that are known to all companies. */
 
	RailTypes rts = (RailTypes)UINT16_MAX;
 

	
 
	/* We are at, or past the introduction date of the rail. */
 
	Company *c;
 
	FOR_ALL_COMPANIES(c) {
 
		c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes, _date);
 
		rts &= c->avail_railtypes;
 
	}
 

	
 
	_introduced_railtypes |= rts;
 
}
 

	
 
void ShowEnginePreviewWindow(EngineID engine);
 

	
 
@@ -602,6 +629,19 @@ void StartupEngines()
 
		c->avail_roadtypes = GetCompanyRoadtypes(c->index);
 
	}
 

	
 
	/* Rail types that are invalid or never introduced are marked as
 
	 * being introduced upon start. That way we can easily check whether
 
	 * there is any date related introduction that is still going to
 
	 * happen somewhere in the future. */
 
	for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
 
		const RailtypeInfo *rti = GetRailTypeInfo(rt);
 
		if (rti->label != 0 && IsInsideMM(rti->introduction_date, 0, MAX_DAY)) continue;
 

	
 
		SetBit(_introduced_railtypes, rt);
 
	}
 

	
 
	CheckRailIntroduction();
 

	
 
	/* Invalidate any open purchase lists */
 
	InvalidateWindowClassesData(WC_BUILD_VEHICLE);
 
}
 
@@ -614,7 +654,7 @@ static void AcceptEnginePreview(EngineID
 
	SetBit(e->company_avail, company);
 
	if (e->type == VEH_TRAIN) {
 
		assert(e->u.rail.railtype < RAILTYPE_END);
 
		c->avail_railtypes |= GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes;
 
		c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes, _date);
 
	} else if (e->type == VEH_ROAD) {
 
		SetBit(c->avail_roadtypes, HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
 
	}
 
@@ -663,6 +703,8 @@ static CompanyID GetBestCompany(uint8 pp
 
/** Daily check to offer an exclusive engine preview to the companies. */
 
void EnginesDailyLoop()
 
{
 
	CheckRailIntroduction();
 

	
 
	if (_cur_year >= _year_engine_aging_stops) return;
 

	
 
	Engine *e;
 
@@ -760,7 +802,7 @@ static void NewVehicleAvailable(Engine *
 
		/* maybe make another rail type available */
 
		RailType railtype = e->u.rail.railtype;
 
		assert(railtype < RAILTYPE_END);
 
		FOR_ALL_COMPANIES(c) c->avail_railtypes |= GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes;
 
		FOR_ALL_COMPANIES(c) c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes, _date);
 
	} else if (e->type == VEH_ROAD) {
 
		/* maybe make another road type available */
 
		FOR_ALL_COMPANIES(c) SetBit(c->avail_roadtypes, HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
src/newgrf.cpp
Show inline comments
 
@@ -3209,6 +3209,7 @@ static ChangeInfoResult RailTypeChangeIn
 

	
 
			case 0x0E: // Compatible railtype list
 
			case 0x0F: // Powered railtype list
 
			case 0x18: // Railtype list required for date introduction
 
			case 0x19: // Introduced railtype list
 
			{
 
				/* Rail type compatibility bits are added to the existing bits
 
@@ -3222,6 +3223,7 @@ static ChangeInfoResult RailTypeChangeIn
 
						switch (prop) {
 
							case 0x0E: SetBit(rti->compatible_railtypes, rt);            break;
 
							case 0x0F: SetBit(rti->powered_railtypes, rt);               break;
 
							case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
 
							case 0x19: SetBit(rti->introduces_railtypes, rt);            break;
 
						}
 
					}
 
@@ -3257,6 +3259,10 @@ static ChangeInfoResult RailTypeChangeIn
 
				rti->map_colour = MapDOSColour(buf->ReadByte());
 
				break;
 

	
 
			case 0x17: // Introduction date
 
				rti->introduction_date = buf->ReadDWord();
 
				break;
 

	
 
			default:
 
				ret = CIR_UNKNOWN;
 
				break;
 
@@ -3304,6 +3310,7 @@ static ChangeInfoResult RailTypeReserveI
 

	
 
			case 0x0E: // Compatible railtype list
 
			case 0x0F: // Powered railtype list
 
			case 0x18: // Railtype list required for date introduction
 
			case 0x19: // Introduced railtype list
 
				for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
 
				break;
 
@@ -3316,6 +3323,10 @@ static ChangeInfoResult RailTypeReserveI
 
				buf->ReadByte();
 
				break;
 

	
 
			case 0x17: // Introduction date
 
				buf->ReadDWord();
 
				break;
 

	
 
			default:
 
				ret = CIR_UNKNOWN;
 
				break;
src/rail.cpp
Show inline comments
 
@@ -192,6 +192,40 @@ RailType GetBestRailtype(const CompanyID
 
	return RAILTYPE_RAIL;
 
}
 

	
 
/**
 
 * Add the rail types that are to be introduced at the given date.
 
 * @param current The currently available railtypes.
 
 * @param date    The date for the introduction comparisions.
 
 * @return The rail types that should be available when date
 
 *         introduced rail types are taken into account as well.
 
 */
 
RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date)
 
{
 
	RailTypes rts = current;
 

	
 
	for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
 
		const RailtypeInfo *rti = GetRailTypeInfo(rt);
 
		/* Unused rail type. */
 
		if (rti->label == 0) continue;
 

	
 
		/* Not date introduced. */
 
		if (!IsInsideMM(rti->introduction_date, 0, MAX_DAY)) continue;
 

	
 
		/* Not yet introduced at this date. */
 
		if (rti->introduction_date > date) continue;
 

	
 
		/* Have we introduced all required railtypes? */
 
		RailTypes required = rti->introduction_required_railtypes;
 
		if ((rts & required) != required) continue;
 

	
 
		rts |= rti->introduces_railtypes;
 
	}
 

	
 
	/* When we added railtypes we need to run this method again; the added
 
	 * railtypes might enable more rail types to become introduced. */
 
	return rts == current ? rts : AddDateIntroducedRailTypes(rts, date);
 
}
 

	
 
RailTypes GetCompanyRailtypes(CompanyID company)
 
{
 
	RailTypes rts = RAILTYPES_NONE;
 
@@ -211,7 +245,7 @@ RailTypes GetCompanyRailtypes(CompanyID 
 
		}
 
	}
 

	
 
	return rts;
 
	return AddDateIntroducedRailTypes(rts, _date);
 
}
 

	
 
RailType GetRailTypeByLabel(RailTypeLabel label)
src/rail.h
Show inline comments
 
@@ -19,6 +19,7 @@
 
#include "economy_func.h"
 
#include "slope_type.h"
 
#include "strings_type.h"
 
#include "date_type.h"
 

	
 
/** Railtype flags. */
 
enum RailTypeFlags {
 
@@ -217,6 +218,21 @@ struct RailtypeInfo {
 
	byte map_colour;
 

	
 
	/**
 
	 * Introduction date.
 
	 * When #INVALID_DATE or a vehicle using this railtype gets introduced earlier,
 
	 * the vehicle's introduction date will be used instead for this railtype.
 
	 * The introduction at this date is furthermore limited by the
 
	 * #introduction_required_types.
 
	 */
 
	Date introduction_date;
 

	
 
	/**
 
	 * Bitmask of railtypes that are required for this railtype to be introduced
 
	 * at a given #introduction_date.
 
	 */
 
	RailTypes introduction_required_railtypes;
 

	
 
	/**
 
	 * Bitmask of which other railtypes are introduced when this railtype is introduced.
 
	 */
 
	RailTypes introduces_railtypes;
 
@@ -368,6 +384,8 @@ bool ValParamRailtype(const RailType rai
 
 */
 
RailType GetBestRailtype(const CompanyID company);
 

	
 
RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date);
 

	
 
/**
 
 * Get the rail types the given company can build.
 
 * @param c the company to get the rail types for.
src/table/railtypes.h
Show inline comments
 
@@ -95,6 +95,12 @@ static const RailtypeInfo _original_rail
 
		/* map colour */
 
		0x0A,
 

	
 
		/* introduction date */
 
		INVALID_DATE,
 

	
 
		/* railtypes required for this to be introduced */
 
		RAILTYPES_NONE,
 

	
 
		/* introduction rail types */
 
		RAILTYPES_RAIL,
 

	
 
@@ -181,6 +187,12 @@ static const RailtypeInfo _original_rail
 
		/* map colour */
 
		0x0A,
 

	
 
		/* introduction date */
 
		INVALID_DATE,
 

	
 
		/* railtypes required for this to be introduced */
 
		RAILTYPES_NONE,
 

	
 
		/* introduction rail types */
 
		RAILTYPES_ELECTRIC,
 

	
 
@@ -263,6 +275,12 @@ static const RailtypeInfo _original_rail
 
		/* map colour */
 
		0x0A,
 

	
 
		/* introduction date */
 
		INVALID_DATE,
 

	
 
		/* railtypes required for this to be introduced */
 
		RAILTYPES_NONE,
 

	
 
		/* introduction rail types */
 
		RAILTYPES_MONO,
 

	
 
@@ -345,6 +363,12 @@ static const RailtypeInfo _original_rail
 
		/* map colour */
 
		0x0A,
 

	
 
		/* introduction date */
 
		INVALID_DATE,
 

	
 
		/* railtypes required for this to be introduced */
 
		RAILTYPES_NONE,
 

	
 
		/* introduction rail types */
 
		RAILTYPES_MAGLEV,
 

	
src/toolbar_gui.cpp
Show inline comments
 
@@ -703,6 +703,9 @@ static CallBackFunction ToolbarBuildRail
 
		used_railtypes |= GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes;
 
	}
 

	
 
	/* Get the date introduced railtypes as well. */
 
	used_railtypes = AddDateIntroducedRailTypes(used_railtypes, MAX_DAY);
 

	
 
	const Company *c = Company::Get(_local_company);
 
	DropDownList *list = new DropDownList();
 
	for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
0 comments (0 inline, 0 general)