From ee0fcb25670d1b559cdfdb31e6b7d0da4ec3713d Mon Sep 17 00:00:00 2001 From: michi_cc Date: Thu, 5 Jan 2012 19:40:34 +0000 Subject: (svn r23758) -Feature: [NewGRF] Alternate rail type label list. --- src/newgrf.cpp | 22 ++++++++++++++++++++-- src/rail.cpp | 11 ++++++++++- src/rail.h | 10 +++++++++- src/rail_cmd.cpp | 3 +++ src/table/railtypes.h | 12 ++++++++++++ 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 970ccec25..b8c75107e 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -3894,7 +3894,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR int n = buf->ReadByte(); for (int j = 0; j != n; j++) { RailTypeLabel label = buf->ReadDWord(); - RailType rt = GetRailTypeByLabel(BSWAP32(label)); + RailType rt = GetRailTypeByLabel(BSWAP32(label), false); if (rt != INVALID_RAILTYPE) { switch (prop) { case 0x0E: SetBit(rti->compatible_railtypes, rt); break; @@ -3952,6 +3952,11 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR rti->maintenance_multiplier = buf->ReadWord(); break; + case 0x1D: // Alternate rail type label list + /* Skipped here as this is loaded during reservation stage. */ + for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord(); + break; + default: ret = CIR_UNKNOWN; break; @@ -3965,6 +3970,8 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte { ChangeInfoResult ret = CIR_SUCCESS; + extern RailtypeInfo _railtypes[RAILTYPE_END]; + if (id + numinfo > RAILTYPE_END) { grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END); return CIR_INVALID_ID; @@ -3977,7 +3984,7 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte RailTypeLabel rtl = buf->ReadDWord(); rtl = BSWAP32(rtl); - RailType rt = GetRailTypeByLabel(rtl); + RailType rt = GetRailTypeByLabel(rtl, false); if (rt == INVALID_RAILTYPE) { /* Set up new rail type */ rt = AllocateRailType(rtl); @@ -3999,6 +4006,17 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte buf->ReadWord(); break; + case 0x1D: // Alternate rail type label list + if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) { + int n = buf->ReadByte(); + for (int j = 0; j != n; j++) { + *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord()); + } + break; + } + grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i); + /* FALL THROUGH */ + case 0x0E: // Compatible railtype list case 0x0F: // Powered railtype list case 0x18: // Railtype list required for date introduction diff --git a/src/rail.cpp b/src/rail.cpp index 13346d607..fa0d86c88 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -277,9 +277,10 @@ RailTypes GetCompanyRailtypes(CompanyID company) /** * Get the rail type for a given label. * @param label the railtype label. + * @param allow_alternate_labels Search in the alternate label lists as well. * @return the railtype. */ -RailType GetRailTypeByLabel(RailTypeLabel label) +RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels) { /* Loop through each rail type until the label is found */ for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { @@ -287,6 +288,14 @@ RailType GetRailTypeByLabel(RailTypeLabel label) if (rti->label == label) return r; } + if (allow_alternate_labels) { + /* Test if any rail type defines the label as an alternate. */ + for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { + const RailtypeInfo *rti = GetRailTypeInfo(r); + if (rti->alternate_labels.Contains(label)) return r; + } + } + /* No matching label was found, so it is invalid */ return INVALID_RAILTYPE; } diff --git a/src/rail.h b/src/rail.h index be7a030c5..b8ef0cb12 100644 --- a/src/rail.h +++ b/src/rail.h @@ -96,6 +96,9 @@ enum RailFenceOffset { RFO_SLOPE_NW, }; +/** List of rail type labels. */ +typedef SmallVector RailTypeLabelList; + /** * This struct contains all the info that is needed to draw and construct tracks. */ @@ -208,6 +211,11 @@ struct RailtypeInfo { */ RailTypeLabel label; + /** + * Rail type labels this type provides in addition to the main label. + */ + RailTypeLabelList alternate_labels; + /** * Colour on mini-map */ @@ -404,7 +412,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date); RailType GetBestRailtype(const CompanyID company); RailTypes GetCompanyRailtypes(const CompanyID c); -RailType GetRailTypeByLabel(RailTypeLabel label); +RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels = true); void ResetRailTypes(); void InitRailTypes(); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 8d3dec5e5..49a58fe6d 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -99,6 +99,9 @@ RailType AllocateRailType(RailTypeLabel label) /* Set up new rail type */ memcpy(rti, &_railtypes[RAILTYPE_RAIL], sizeof(*rti)); rti->label = label; + /* Clear alternate label list. Can't use Reset() here as that would free + * the data pointer of RAILTYPE_RAIL and not our new rail type. */ + new (&rti->alternate_labels) RailTypeLabelList; /* Make us compatible with ourself. */ rti->powered_railtypes = (RailTypes)(1 << rt); diff --git a/src/table/railtypes.h b/src/table/railtypes.h index 065f78720..3ff6d9638 100644 --- a/src/table/railtypes.h +++ b/src/table/railtypes.h @@ -93,6 +93,9 @@ static const RailtypeInfo _original_railtypes[] = { /* rail type label */ 'RAIL', + /* alternate labels */ + RailTypeLabelList(), + /* map colour */ 0x0A, @@ -190,6 +193,9 @@ static const RailtypeInfo _original_railtypes[] = { /* rail type label */ 'ELRL', + /* alternate labels */ + RailTypeLabelList(), + /* map colour */ 0x0A, @@ -283,6 +289,9 @@ static const RailtypeInfo _original_railtypes[] = { /* rail type label */ 'MONO', + /* alternate labels */ + RailTypeLabelList(), + /* map colour */ 0x0A, @@ -376,6 +385,9 @@ static const RailtypeInfo _original_railtypes[] = { /* rail type label */ 'MGLV', + /* alternate labels */ + RailTypeLabelList(), + /* map colour */ 0x0A, -- cgit v1.2.3-70-g09d2