From 704a361adac50237d69ea74facf74f63859897a8 Mon Sep 17 00:00:00 2001 From: rubidium Date: Fri, 13 May 2011 17:57:07 +0000 Subject: [PATCH] (svn r22448) [1.1] -Backport from trunk: - Fix: [NewGRF] When GRFs are disabled via Action E or due to GRM failure, also display an error in the GUI (r22444, r22443) - Fix: [NewGRF] Do not popup fatal NewGRF error messages in the intro screen. The GRFs are not going to be activated there anyway and the GRF settings GUI will not display the errors either (r22442) - Fix: Catenary was drawn incorrectly next to level crossings with foundations (r22437) - Fix: [NewGRF] Apply railtype property 12 (station graphics) also to station groundsprites from action 1 (r22436) --- src/elrail.cpp | 7 ++-- src/lang/english.txt | 2 + src/newgrf.cpp | 90 +++++++++++++++++++++--------------------- src/newgrf_gui.cpp | 3 ++ src/newgrf_station.cpp | 6 +-- src/rail.h | 26 ++++++------ src/rail_cmd.cpp | 8 ++-- src/station_cmd.cpp | 6 +-- src/table/railtypes.h | 20 ++-------- 9 files changed, 81 insertions(+), 87 deletions(-) diff --git a/src/elrail.cpp b/src/elrail.cpp index 701d17a26a..3fb88122db 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -310,7 +310,6 @@ static void DrawCatenaryRailway(const TileInfo *ti) }; SpriteID pylon_base = (halftile_corner != CORNER_INVALID && HasBit(edge_corners[i], halftile_corner)) ? pylon_halftile : pylon_normal; TileIndex neighbour = ti->tile + TileOffsByDiagDir(i); - Foundation foundation = FOUNDATION_NONE; byte elevation = GetPCPElevation(ti->tile, i); /* Here's one of the main headaches. GetTileSlope does not correct for possibly @@ -361,8 +360,10 @@ static void DrawCatenaryRailway(const TileInfo *ti) PPPallowed[i] = 0; } - /* A station is always "flat", so adjust the tileh accordingly */ - if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; + Foundation foundation = FOUNDATION_NONE; + + /* Station and road crossings are always "flat", so adjust the tileh accordingly */ + if (IsTileType(neighbour, MP_STATION) || IsTileType(neighbour, MP_ROAD)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; /* Read the foundataions if they are present, and adjust the tileh */ if (trackconfig[TS_NEIGHBOUR] != TRACK_BIT_NONE && IsTileType(neighbour, MP_RAILWAY) && HasCatenary(GetRailType(neighbour))) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]); diff --git a/src/lang/english.txt b/src/lang/english.txt index b6c55c2c72..73db071a9e 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2483,6 +2483,8 @@ STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{RAW_ST STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Contains multiple Action 8 entries STR_NEWGRF_ERROR_READ_BOUNDS :Read past end of pseudo-sprite STR_NEWGRF_ERROR_MISSING_SPRITES :{WHITE}The currently used base graphics set is missing a number of sprites.{}Please update the base graphics set +STR_NEWGRF_ERROR_GRM_FAILED :Requested GRF resources not available +STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{2:RAW_STRING} was disabled by {4:RAW_STRING} # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Caution! diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 450bc8241d..a252a8a1fd 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -282,6 +282,34 @@ static void ClearTemporaryNewGRFData(GRFFile *gf) gf->spritegroups_count = 0; } +/** + * Disable a GRF + * @param message Error message or STR_NULL + * @param config GRFConfig to disable, NULL for current + * @return Error message of the GRF for further customisation + */ +static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL) +{ + GRFFile *file; + if (config != NULL) { + file = GetFileByGRFID(config->ident.grfid); + } else { + config = _cur_grfconfig; + file = _cur_grffile; + } + + config->status = GCS_DISABLED; + if (file != NULL) ClearTemporaryNewGRFData(file); + if (config == _cur_grfconfig) _skip_sprites = -1; + + if (message != STR_NULL) { + delete config->error; + config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message); + } + + return config->error; +} + typedef std::map StringIDToGRFIDMapping; static StringIDToGRFIDMapping _string_to_grf_mapping; @@ -3288,7 +3316,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR break; case 0x12: // Station graphic - rti->total_offset = Clamp(buf->ReadByte(), 0, 2) * 82; + rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2); break; case 0x13: // Construction cost factor @@ -3497,11 +3525,7 @@ static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uin case CIR_INVALID_ID: /* No debug message for an invalid ID, as it has already been output */ - _skip_sprites = -1; - _cur_grfconfig->status = GCS_DISABLED; - delete _cur_grfconfig->error; - _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL); - _cur_grfconfig->error->message = (cir == CIR_INVALID_ID) ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY; + DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY); return true; } } @@ -5224,12 +5248,8 @@ static void CfgApply(ByteReader *buf) */ static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c) { - delete c->error; - c->status = GCS_DISABLED; - c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC); - c->error->data = strdup(_cur_grfconfig->GetName()); - - ClearTemporaryNewGRFData(GetFileByGRFID(c->ident.grfid)); + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c); + error->data = strdup(_cur_grfconfig->GetName()); } /* Action 0x07 @@ -5391,8 +5411,7 @@ static void SkipIf(ByteReader *buf) /* If an action 8 hasn't been encountered yet, disable the grf. */ if (_cur_grfconfig->status != (_cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) { - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); + DisableGrf(); } } } @@ -5442,11 +5461,7 @@ static void GRFInfo(ByteReader *buf) const char *name = buf->ReadString(); if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) { - _cur_grfconfig->status = GCS_DISABLED; - delete _cur_grfconfig->error; - _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_MULTIPLE_ACTION_8); - - _skip_sprites = -1; + DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8); return; } @@ -5571,9 +5586,7 @@ static void GRFLoadError(ByteReader *buf) } else if (severity == 3) { /* This is a fatal error, so make sure the GRF is deactivated and no * more of it gets loaded. */ - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; + DisableGrf(); } if (message_id >= lengthof(msgstr) && message_id != 0xFF) { @@ -5755,9 +5768,7 @@ static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, ui if (op != 4 && op != 5) { /* Deactivate GRF */ grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type); - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; + DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED); return UINT_MAX; } @@ -5832,9 +5843,7 @@ static void ParamSet(ByteReader *buf) /* Check if the allocated sprites will fit below the original sprite limit */ if (_cur_spriteid + count >= 16384) { grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count); - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; + DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED); return; } @@ -6111,7 +6120,8 @@ static void GRFInhibit(ByteReader *buf) /* Unset activation flag */ if (file != NULL && file != _cur_grfconfig) { grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename); - file->status = GCS_DISABLED; + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file); + error->data = strdup(_cur_grfconfig->GetName()); } } } @@ -6182,9 +6192,7 @@ static void FeatureTownName(ByteReader *buf) if (townname->nbparts[ref_id] == 0) { grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id); DelGRFTownName(grfid); - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; + DisableGrf(STR_NEWGRF_ERROR_INVALID_ID); return; } @@ -6459,16 +6467,12 @@ static void TranslateGRFStrings(ByteReader *buf) if (c->status == GCS_INITIALISED) { /* If the file is not active but will be activated later, give an error * and disable this file. */ - delete _cur_grfconfig->error; - _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_LOAD_AFTER); + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER); char tmp[256]; GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp)); - _cur_grfconfig->error->data = strdup(tmp); + error->data = strdup(tmp); - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; return; } @@ -7914,11 +7918,7 @@ static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage) } } catch (...) { grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data"); - - _skip_sprites = -1; - _cur_grfconfig->status = GCS_DISABLED; - delete _cur_grfconfig->error; - _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_READ_BOUNDS); + DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS); } } @@ -7993,9 +7993,7 @@ void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage) } else { if (_skip_sprites == 0) { grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling"); - config->status = GCS_DISABLED; - delete config->error; - config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_UNEXPECTED_SPRITE); + DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE); break; } diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index a1e45e3cc2..9ff94b7e0d 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -34,6 +34,9 @@ */ void ShowNewGRFError() { + /* Do not show errors when entering the main screen */ + if (_game_mode == GM_MENU) return; + for (const GRFConfig *c = _grfconfig; c != NULL; c = c->next) { /* We only want to show fatal errors */ if (c->error == NULL || c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL) continue; diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index d93b3467a9..83f7b03eb8 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -768,14 +768,14 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID PaletteID pal = sprites->ground.pal; if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) { image += GetCustomStationGroundRelocation(statspec, NULL, INVALID_TILE); - image += rti->custom_ground_offset; + image += rti->fallback_railtype; } else { - image += rti->total_offset; + image += rti->GetRailtypeSpriteOffset(); } DrawSprite(image, GroundSpritePaletteTransform(image, pal, palette), x, y); - DrawRailTileSeqInGUI(x, y, sprites, rti->total_offset, relocation, palette); + DrawRailTileSeqInGUI(x, y, sprites, rti->GetRailtypeSpriteOffset(), relocation, palette); return true; } diff --git a/src/rail.h b/src/rail.h index 586b853247..067db79571 100644 --- a/src/rail.h +++ b/src/rail.h @@ -162,25 +162,15 @@ struct RailtypeInfo { /** bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel */ RailTypes compatible_railtypes; - /** - * Offset between the current railtype and normal rail. This means that:

- * 1) All the sprites in a railset MUST be in the same order. This order - * is determined by normal rail. Check sprites 1005 and following for this order

- * 2) The position where the railtype is loaded must always be the same, otherwise - * the offset will fail. - * @note: Something more flexible might be desirable in the future. - */ - SpriteID total_offset; - /** * Bridge offset */ SpriteID bridge_offset; /** - * Offset to add to ground sprite when drawing custom waypoints / stations + * Original railtype number to use when drawing non-newgrf railtypes, or when drawing stations. */ - byte custom_ground_offset; + byte fallback_railtype; /** * Multiplier for curve maximum speed advantage @@ -251,6 +241,18 @@ struct RailtypeInfo { { return this->group[RTSG_GROUND] != NULL; } + + /** + * Offset between the current railtype and normal rail. This means that:

+ * 1) All the sprites in a railset MUST be in the same order. This order + * is determined by normal rail. Check sprites 1005 and following for this order

+ * 2) The position where the railtype is loaded must always be the same, otherwise + * the offset will fail. + */ + inline uint GetRailtypeSpriteOffset() const + { + return 82 * this->fallback_railtype; + } }; diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 9908316901..cc5162d575 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -2247,7 +2247,7 @@ static void DrawTile_Track(TileInfo *ti) image = SPR_FLAT_GRASS_TILE; } else { image = dts->ground.sprite; - if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset; + if (image != SPR_FLAT_GRASS_TILE) image += rti->GetRailtypeSpriteOffset(); } /* adjust ground tile for desert @@ -2286,7 +2286,7 @@ static void DrawTile_Track(TileInfo *ti) } int depot_sprite = GetCustomRailSprite(rti, ti->tile, RTSG_DEPOT); - relocation = depot_sprite != 0 ? depot_sprite - SPR_RAIL_DEPOT_SE_1 : rti->total_offset; + relocation = depot_sprite != 0 ? depot_sprite - SPR_RAIL_DEPOT_SE_1 : rti->GetRailtypeSpriteOffset(); } else { /* PBS debugging, draw reserved tracks darker */ if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) { @@ -2299,7 +2299,7 @@ static void DrawTile_Track(TileInfo *ti) } } - relocation = rti->total_offset; + relocation = rti->GetRailtypeSpriteOffset(); } if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti); @@ -2314,7 +2314,7 @@ void DrawTrainDepotSprite(int x, int y, int dir, RailType railtype) const DrawTileSprites *dts = &_depot_gfx_table[dir]; const RailtypeInfo *rti = GetRailTypeInfo(railtype); SpriteID image = rti->UsesOverlay() ? SPR_FLAT_GRASS_TILE : dts->ground.sprite; - uint32 offset = rti->total_offset; + uint32 offset = rti->GetRailtypeSpriteOffset(); x += 33; y += 17; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 859753325c..418056d1f9 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2500,8 +2500,8 @@ static void DrawTile_Station(TileInfo *ti) if (HasStationRail(ti->tile)) { rti = GetRailTypeInfo(GetRailType(ti->tile)); roadtypes = ROADTYPES_NONE; - total_offset = rti->total_offset; - custom_ground_offset = rti->custom_ground_offset; + total_offset = rti->GetRailtypeSpriteOffset(); + custom_ground_offset = rti->fallback_railtype; if (IsCustomStationSpecIndex(ti->tile)) { /* look for customization */ @@ -2706,7 +2706,7 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro if (railtype != INVALID_RAILTYPE) { rti = GetRailTypeInfo(railtype); - total_offset = rti->total_offset; + total_offset = rti->GetRailtypeSpriteOffset(); } SpriteID img = t->ground.sprite; diff --git a/src/table/railtypes.h b/src/table/railtypes.h index e8a1d51e56..191714028b 100644 --- a/src/table/railtypes.h +++ b/src/table/railtypes.h @@ -65,13 +65,10 @@ static const RailtypeInfo _original_railtypes[] = { /* Compatible railtypes */ RAILTYPES_RAIL | RAILTYPES_ELECTRIC, - /* main offset */ - 0, - /* bridge offset */ 0, - /* custom ground offset */ + /* fallback_railtype */ 0, /* curve speed advantage (multiplier) */ @@ -160,13 +157,10 @@ static const RailtypeInfo _original_railtypes[] = { /* Compatible railtypes */ RAILTYPES_ELECTRIC | RAILTYPES_RAIL, - /* main offset */ - 0, - /* bridge offset */ 0, - /* custom ground offset */ + /* fallback_railtype */ 0, /* curve speed advantage (multiplier) */ @@ -251,13 +245,10 @@ static const RailtypeInfo _original_railtypes[] = { /* Compatible Railtypes */ RAILTYPES_MONO, - /* main offset */ - 82, - /* bridge offset */ 16, - /* custom ground offset */ + /* fallback_railtype */ 1, /* curve speed advantage (multiplier) */ @@ -342,13 +333,10 @@ static const RailtypeInfo _original_railtypes[] = { /* Compatible Railtypes */ RAILTYPES_MAGLEV, - /* main offset */ - 164, - /* bridge offset */ 24, - /* custom ground offset */ + /* fallback_railtype */ 2, /* curve speed advantage (multiplier) */