(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

This commit is contained in:
rubidium 2011-01-18 21:30:59 +00:00
parent 6371b75bcc
commit b8c9988d9f
6 changed files with 135 additions and 3 deletions

View File

@ -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 eid, CompanyID company)
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 *e)
/* 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);

View File

@ -3209,6 +3209,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR
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 RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR
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 RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR
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 RailTypeReserveInfo(uint id, int numinfo, int prop, Byte
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 RailTypeReserveInfo(uint id, int numinfo, int prop, Byte
buf->ReadByte();
break;
case 0x17: // Introduction date
buf->ReadDWord();
break;
default:
ret = CIR_UNKNOWN;
break;

View File

@ -192,6 +192,40 @@ RailType GetBestRailtype(const CompanyID company)
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 company)
}
}
return rts;
return AddDateIntroducedRailTypes(rts, _date);
}
RailType GetRailTypeByLabel(RailTypeLabel label)

View File

@ -19,6 +19,7 @@
#include "economy_func.h"
#include "slope_type.h"
#include "strings_type.h"
#include "date_type.h"
/** Railtype flags. */
enum RailTypeFlags {
@ -216,6 +217,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.
*/
@ -368,6 +384,8 @@ bool ValParamRailtype(const RailType rail);
*/
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.

View File

@ -95,6 +95,12 @@ static const RailtypeInfo _original_railtypes[] = {
/* 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_railtypes[] = {
/* 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_railtypes[] = {
/* 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_railtypes[] = {
/* map colour */
0x0A,
/* introduction date */
INVALID_DATE,
/* railtypes required for this to be introduced */
RAILTYPES_NONE,
/* introduction rail types */
RAILTYPES_MAGLEV,

View File

@ -703,6 +703,9 @@ static CallBackFunction ToolbarBuildRailClick(Window *w)
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++) {